Skip to content

Automate PMM HA installation on Linode LKE cluster - #1129

Open
shrutipradhan-percona wants to merge 2 commits into
mainfrom
PMM-14744
Open

Automate PMM HA installation on Linode LKE cluster#1129
shrutipradhan-percona wants to merge 2 commits into
mainfrom
PMM-14744

Conversation

@shrutipradhan-percona

@shrutipradhan-percona shrutipradhan-percona commented Aug 3, 2026

Copy link
Copy Markdown

This script covers -

  • Create LKE cluster on Linode
  • Install Dependencies
  • Install PMM HA
  • Enable external access - Load balancer
  • Gives Cluster summary
  • Get pods and event logs

Summary by CodeRabbit

  • New Features
    • Added an automated workflow for creating and configuring a Kubernetes cluster.
    • Added automated installation and deployment of PMM High Availability components.
    • Added LoadBalancer exposure for accessing the deployed service.
    • Added readiness checks, credential setup, and diagnostic data collection.
    • Added validation and error handling for required tools, configuration, and cluster status.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The new Bash script creates an LKE cluster, configures kubeconfig access, installs PMM HA dependencies and credentials, deploys PMM HA, exposes HAProxy through a LoadBalancer, and collects diagnostics.

Changes

LKE PMM HA deployment

Layer / File(s) Summary
LKE cluster bootstrap
k8s/createLKE_install_PMM_HA.sh
The script validates required commands, creates an LKE cluster, discovers its ID, and waits for readiness.
Cluster access and verification
k8s/createLKE_install_PMM_HA.sh
The script downloads and exports kubeconfig, validates the file, and checks the Kubernetes context, nodes, and system pods.
PMM dependency setup
k8s/createLKE_install_PMM_HA.sh
The script creates the PMM namespace, installs Helm dependencies, waits for operators, and creates pmm-secret with PMM component credentials.
PMM HA deployment and exposure
k8s/createLKE_install_PMM_HA.sh
The script installs PMM HA, waits for HAProxy, exposes the service through a LoadBalancer, waits for its external IP, and saves diagnostic output.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Operator
  participant BashScript
  participant LinodeLKE
  participant Kubernetes
  participant Helm
  Operator->>BashScript: Run deployment script
  BashScript->>LinodeLKE: Create and verify LKE cluster
  BashScript->>LinodeLKE: Download kubeconfig
  BashScript->>Kubernetes: Verify cluster and create namespace
  BashScript->>Helm: Install PMM dependencies and PMM HA
  BashScript->>Kubernetes: Wait for operators and HAProxy
  BashScript->>Kubernetes: Expose HAProxy service
  Kubernetes-->>BashScript: Return LoadBalancer external IP
  BashScript->>Kubernetes: Collect pod and event diagnostics
Loading

Suggested reviewers: petersirotnak, yurkovychv

Poem

A rabbit hops through Helm’s bright trail,
Builds an LKE cluster without fail.
PMM pods rise, credentials flow,
LoadBalancer lights the endpoint glow.
Logs rest softly where diagnostics grow.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: automating PMM HA installation on a Linode LKE cluster.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch PMM-14744

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@k8s/createLKE_install_PMM_HA.sh`:
- Around line 84-103: Replace the predictable /tmp/HA-linode directory in the
kubeconfig setup with a uniquely created, restrictive mktemp -d directory and
store kubeconfig within it, updating KUBECONFIG and validation accordingly. Also
update the diagnostics block at k8s/createLKE_install_PMM_HA.sh lines 208-211 to
use a separate unique mktemp -d directory for all diagnostic artifacts.
- Around line 58-66: Bound both polling loops in
k8s/createLKE_install_PMM_HA.sh: the cluster lookup loop around lines 58-66 and
the LoadBalancer ingress wait around line 200. Add a clear deadline or timeout
counter to each, and when exceeded, report a useful failure and exit instead of
continuing indefinitely.
- Around line 74-77: Replace the single readiness check and fixed sleep after
“Waiting for cluster to become READY...” with a polling loop that repeatedly
evaluates the ready-node count against NODE_COUNT, sleeps between attempts, and
proceeds only when all nodes are ready. Add a defined timeout/deadline; when it
expires, print an error and exit nonzero before kubeconfig or Helm operations
continue.
- Around line 82-83: Remove the rm command targeting ~/.kube/config and keep the
script’s kubeconfig isolated through its script-specific KUBECONFIG path.
Preserve existing user kubeconfig files and contexts while ensuring subsequent
kubectl operations continue using only the temporary configuration.
- Around line 165-173: Replace the hardcoded credentials in the pmm-secret
creation command with unique values supplied through protected deployment inputs
or a secure secret store. Ensure the PMM_ADMIN_PASSWORD and all other password
fields are not fixed literals, and preserve the existing secret keys and
namespace.
- Around line 23-28: Update the prerequisite command loop in
createLKE_install_PMM_HA.sh to include helm alongside linode-cli, jq, kubectl,
and base64, ensuring helm is validated before any cloud resources are created.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6a243d77-b4ef-455e-baa3-3b27a6a8b16f

📥 Commits

Reviewing files that changed from the base of the PR and between 15bc85a and 76d5a9a.

📒 Files selected for processing (1)
  • k8s/createLKE_install_PMM_HA.sh

Comment on lines +23 to +28
for cmd in linode-cli jq kubectl base64; do
if ! command -v "$cmd" >/dev/null 2>&1; then
echo "ERROR: '$cmd' is not installed."
exit 1
fi
done

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Validate helm before creating cloud resources.

The script invokes helm at Line 143. The prerequisite loop does not validate it. If helm is absent, the script creates the LKE cluster and then fails during installation.

Proposed fix
-for cmd in linode-cli jq kubectl base64; do
+for cmd in linode-cli jq kubectl base64 helm; do
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for cmd in linode-cli jq kubectl base64; do
if ! command -v "$cmd" >/dev/null 2>&1; then
echo "ERROR: '$cmd' is not installed."
exit 1
fi
done
for cmd in linode-cli jq kubectl base64 helm; do
if ! command -v "$cmd" >/dev/null 2>&1; then
echo "ERROR: '$cmd' is not installed."
exit 1
fi
done
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@k8s/createLKE_install_PMM_HA.sh` around lines 23 - 28, Update the
prerequisite command loop in createLKE_install_PMM_HA.sh to include helm
alongside linode-cli, jq, kubectl, and base64, ensuring helm is validated before
any cloud resources are created.

Comment on lines +58 to +66
while [ -z "$CLUSTER_ID" ] || [ "$CLUSTER_ID" = "null" ]; do
CLUSTER_ID=$(linode-cli lke clusters-list --json | jq -r --arg label "$CLUSTER_LABEL" '.[] | select(.label | contains($label)) | .id')

if [ -z "$CLUSTER_ID" ] || [ "$CLUSTER_ID" = "null" ]; then
echo "Waiting for cluster to appear..."
sleep 10
CLUSTER_ID="" # Reset to ensure the loop expression evaluates correctly next turn
fi
done

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Add deadlines to polling loops.

Both loops can run forever when the provider reports a persistent failure. The script then never returns control or reports a useful failure.

  • k8s/createLKE_install_PMM_HA.sh#L58-L66: enforce a deadline while waiting for the created cluster to appear.
  • k8s/createLKE_install_PMM_HA.sh#L200-L200: enforce a deadline while waiting for the LoadBalancer ingress address.
📍 Affects 1 file
  • k8s/createLKE_install_PMM_HA.sh#L58-L66 (this comment)
  • k8s/createLKE_install_PMM_HA.sh#L200-L200
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@k8s/createLKE_install_PMM_HA.sh` around lines 58 - 66, Bound both polling
loops in k8s/createLKE_install_PMM_HA.sh: the cluster lookup loop around lines
58-66 and the LoadBalancer ingress wait around line 200. Add a clear deadline or
timeout counter to each, and when exceeded, report a useful failure and exit
instead of continuing indefinitely.

Comment on lines +74 to +77
echo "Waiting for cluster to become READY..."

[ $(linode-cli lke pools-list "$CLUSTER_ID" --json | jq '.[] | .nodes[] | select(.status == "ready")' | jq -s 'length') -eq $NODE_COUNT ] && echo "Cluster is READY"
sleep 90

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Poll node readiness until a bounded deadline.

Line 76 performs one readiness check. The script continues after Line 77 even when fewer than NODE_COUNT nodes are ready. The kubeconfig and later Helm operations can then fail against a cluster that is still provisioning.

Replace the fixed sleep with a retry loop that exits with an error at a defined deadline.

🧰 Tools
🪛 Shellcheck (0.11.0)

[warning] 76-76: Quote this to prevent word splitting.

(SC2046)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@k8s/createLKE_install_PMM_HA.sh` around lines 74 - 77, Replace the single
readiness check and fixed sleep after “Waiting for cluster to become READY...”
with a polling loop that repeatedly evaluates the ready-node count against
NODE_COUNT, sleeps between attempts, and proceeds only when all nodes are ready.
Add a defined timeout/deadline; when it expires, print an error and exit nonzero
before kubeconfig or Helm operations continue.

Comment thread k8s/createLKE_install_PMM_HA.sh
Comment on lines +84 to +103
mkdir -p /tmp/HA-linode

# Download kubeconfig
linode-cli lke kubeconfig-view "$CLUSTER_ID" --json \
| jq -r '.[0].kubeconfig' \
| base64 --decode > /tmp/HA-linode/kubeconfig.yaml

# Export KUBECONFIG
export KUBECONFIG=/tmp/HA-linode/kubeconfig.yaml
#cp /Users/shruti/Scripts/HA-linode/kubeconfig.yaml ~/.kube/config
#chmod 600 ~/.kube/config
echo "KUBECONFIG exported: $KUBECONFIG"

if [ -f /tmp/HA-linode/kubeconfig.yaml ]; then
export KUBECONFIG=/tmp/HA-linode/kubeconfig.yaml
echo "Kubeconfig downloaded successfully."
else
echo "ERROR: Failed to download kubeconfig."
exit 1
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Use private, unique temporary directories.

Both diagnostic paths are predictable shared paths under /tmp. Another local user can pre-create these paths or symlinks. The kubeconfig path can expose or overwrite credential data.

  • k8s/createLKE_install_PMM_HA.sh#L84-L103: create a unique mktemp -d directory with restrictive permissions and store the kubeconfig inside it.
  • k8s/createLKE_install_PMM_HA.sh#L208-L211: create a separate unique mktemp -d directory for diagnostics and write all artifacts there.
🧰 Tools
🪛 ast-grep (0.45.0)

[warning] 88-88: Writing to or reading from a hardcoded, predictable path under /tmp is vulnerable to symlink and TOCTOU attacks: a local attacker can pre-create the file (or a symlink pointing elsewhere) and hijack or corrupt the contents. Generate a unique, unpredictable temporary file with mktemp instead, e.g. tmpfile="$(mktemp)" (or mktemp -d for directories) and reference "$tmpfile".
Context: /tmp/HA-linode/kubeconfig.yaml
Note: [CWE-377] Insecure Temporary File.

(predictable-tmp-file-bash)


[warning] 96-96: Writing to or reading from a hardcoded, predictable path under /tmp is vulnerable to symlink and TOCTOU attacks: a local attacker can pre-create the file (or a symlink pointing elsewhere) and hijack or corrupt the contents. Generate a unique, unpredictable temporary file with mktemp instead, e.g. tmpfile="$(mktemp)" (or mktemp -d for directories) and reference "$tmpfile".
Context: /tmp/HA-linode/kubeconfig.yaml
Note: [CWE-377] Insecure Temporary File.

(predictable-tmp-file-bash)

📍 Affects 1 file
  • k8s/createLKE_install_PMM_HA.sh#L84-L103 (this comment)
  • k8s/createLKE_install_PMM_HA.sh#L208-L211
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@k8s/createLKE_install_PMM_HA.sh` around lines 84 - 103, Replace the
predictable /tmp/HA-linode directory in the kubeconfig setup with a uniquely
created, restrictive mktemp -d directory and store kubeconfig within it,
updating KUBECONFIG and validation accordingly. Also update the diagnostics
block at k8s/createLKE_install_PMM_HA.sh lines 208-211 to use a separate unique
mktemp -d directory for all diagnostic artifacts.

Source: Linters/SAST tools

Comment thread k8s/createLKE_install_PMM_HA.sh
Added PMM password as a parameter and generated random passwords for Clickhouse, Postgres, Grafana, and VM. Updated echo statements to display the generated passwords and external IP.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
k8s/createLKE_install_PMM_HA.sh (3)

23-28: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Check openssl before creating cloud resources.

The script invokes openssl at Lines 161-164, but the prerequisite loop does not validate it. If openssl is missing, the script creates the cluster and installs dependencies before failing during secret generation.

Proposed fix
-for cmd in linode-cli jq kubectl base64; do
+for cmd in linode-cli jq kubectl base64 openssl; do
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@k8s/createLKE_install_PMM_HA.sh` around lines 23 - 28, Update the
prerequisite command loop in the script to include openssl alongside linode-cli,
jq, kubectl, and base64, ensuring it is validated before any cloud resources are
created and before the later secret-generation usage.

59-59: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Use exact cluster label match instead of substring match.

The filter .label | contains($label) matches any cluster label that contains the substring. If multiple clusters match (for example, "pmm-prod" and "pmm-staging" when searching for "pmm"), then CLUSTER_ID will contain multiple IDs separated by newlines. Subsequent commands that use $CLUSTER_ID will then target an unpredictable cluster or fail.

Use .label == $label to match only the exact label, or capture the cluster ID directly from the cluster-create output if possible.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@k8s/createLKE_install_PMM_HA.sh` at line 59, Update the CLUSTER_ID assignment
to filter cluster objects by exact label equality using the existing
CLUSTER_LABEL value, replacing the substring-based matching in the jq
expression. Preserve the current extraction of the matching cluster’s id.

187-189: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Use a retrying lookup for the HAProxy pod.

If pmm-ha-haproxy does not exist when the command substitution runs, kubectl wait receives no pod resource and exits before the 15-minute timeout. Poll for pod creation or use a stable label selector with an explicit retry loop.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@k8s/createLKE_install_PMM_HA.sh` around lines 187 - 189, Update the HAProxy
readiness wait around the kubectl wait invocation to retry pod discovery until a
pmm-ha-haproxy pod exists, rather than performing a single command-substitution
lookup. Keep polling within the existing 15-minute timeout, then wait for the
discovered pod’s ready condition using the existing pmm namespace and HAProxy
identification.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@k8s/createLKE_install_PMM_HA.sh`:
- Line 14: Validate the PMM_PW argument at the start of the script before any
cloud-resource creation: require exactly one non-empty positional argument,
print a usage message to stderr, and exit nonzero when validation fails. Keep
the existing PMM_PW assignment and downstream secret creation behavior for valid
input.
- Around line 206-210: The current kubectl get pods and kubectl get events
commands collect only pod metadata and events, not actual container logs as
indicated by the section header. Add kubectl logs commands that capture the
actual container output from PMM pods to the /tmp/helm-debug directory. Use the
--all-containers=true flag to handle pods with multiple containers, and apply
the || true pattern to each logs command to maintain the script's resilience
when log collection encounters errors.
- Around line 217-221: Remove the password-printing echo statements for PMM,
ClickHouse, Postgres, Grafana, and VM credentials from the script. Keep the
Kubernetes secret storage unchanged; if the surrounding summary is retained,
limit it to non-sensitive endpoint or deployment-status information.

---

Outside diff comments:
In `@k8s/createLKE_install_PMM_HA.sh`:
- Around line 23-28: Update the prerequisite command loop in the script to
include openssl alongside linode-cli, jq, kubectl, and base64, ensuring it is
validated before any cloud resources are created and before the later
secret-generation usage.
- Line 59: Update the CLUSTER_ID assignment to filter cluster objects by exact
label equality using the existing CLUSTER_LABEL value, replacing the
substring-based matching in the jq expression. Preserve the current extraction
of the matching cluster’s id.
- Around line 187-189: Update the HAProxy readiness wait around the kubectl wait
invocation to retry pod discovery until a pmm-ha-haproxy pod exists, rather than
performing a single command-substitution lookup. Keep polling within the
existing 15-minute timeout, then wait for the discovered pod’s ready condition
using the existing pmm namespace and HAProxy identification.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 982c9e16-c29d-426e-bae2-af56e08f8295

📥 Commits

Reviewing files that changed from the base of the PR and between 76d5a9a and 27a6c82.

📒 Files selected for processing (1)
  • k8s/createLKE_install_PMM_HA.sh

K8S_VERSION="1.36"
NODE_TYPE="g6-standard-4"
NODE_COUNT=7
PMM_PW=$1 #PMM password

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Validate the PMM password argument before creating cloud resources.

With set -u, a missing argument causes an unhelpful shell error at Line 14. An empty argument reaches the secret creation step and writes an empty PMM_ADMIN_PASSWORD. Require exactly one non-empty argument and print a usage error before creating the cluster.

Proposed fix
+if [[ $# -ne 1 || -z "$1" ]]; then
+    echo "Usage: $0 <pmm-password>" >&2
+    exit 2
+fi
-PMM_PW=$1
+PMM_PW="$1"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
PMM_PW=$1 #PMM password
if [[ $# -ne 1 || -z "$1" ]]; then
echo "Usage: $0 <pmm-password>" >&2
exit 2
fi
PMM_PW="$1"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@k8s/createLKE_install_PMM_HA.sh` at line 14, Validate the PMM_PW argument at
the start of the script before any cloud-resource creation: require exactly one
non-empty positional argument, print a usage message to stderr, and exit nonzero
when validation fails. Keep the existing PMM_PW assignment and downstream secret
creation behavior for valid input.

Comment on lines +206 to +210
#Cluster Summary and pod logs
####################################
mkdir -p /tmp/helm-debug
kubectl get pods -n pmm -o wide > /tmp/helm-debug/pods.txt || true
kubectl get events -n pmm --sort-by=.metadata.creationTimestamp > /tmp/helm-debug/events.txt || true

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

# Get file context and check the full section around lines 206-210
wc -l k8s/createLKE_install_PMM_HA.sh
head -220 k8s/createLKE_install_PMM_HA.sh | tail -40

Repository: percona/pmm-qa

Length of output: 1538


🏁 Script executed:

# Search for any existing kubectl logs usage in the file
rg "kubectl logs" k8s/createLKE_install_PMM_HA.sh

Repository: percona/pmm-qa

Length of output: 152


🏁 Script executed:

# Check if there's any kubectl logs collection elsewhere or similar debugging patterns
rg "logs|describe" k8s/createLKE_install_PMM_HA.sh | head -20

Repository: percona/pmm-qa

Length of output: 228


Collect container logs, not only pod metadata.

The section header states "Cluster Summary and pod logs", but kubectl get pods -o wide provides only pod status and details. It does not collect container logs. The inline comment "Pod logs and events at /tmp/helm-debug" is inaccurate—only metadata and events are saved. Add kubectl logs commands for PMM pods to the /tmp/helm-debug directory. Handle multiple containers within pods using the --all-containers=true flag or by specifying container names explicitly. Use || true to preserve script resilience if log collection fails.

🧰 Tools
🪛 ast-grep (0.45.0)

[warning] 208-208: Writing to or reading from a hardcoded, predictable path under /tmp is vulnerable to symlink and TOCTOU attacks: a local attacker can pre-create the file (or a symlink pointing elsewhere) and hijack or corrupt the contents. Generate a unique, unpredictable temporary file with mktemp instead, e.g. tmpfile="$(mktemp)" (or mktemp -d for directories) and reference "$tmpfile".
Context: /tmp/helm-debug/pods.txt
Note: [CWE-377] Insecure Temporary File.

(predictable-tmp-file-bash)


[warning] 209-209: Writing to or reading from a hardcoded, predictable path under /tmp is vulnerable to symlink and TOCTOU attacks: a local attacker can pre-create the file (or a symlink pointing elsewhere) and hijack or corrupt the contents. Generate a unique, unpredictable temporary file with mktemp instead, e.g. tmpfile="$(mktemp)" (or mktemp -d for directories) and reference "$tmpfile".
Context: /tmp/helm-debug/events.txt
Note: [CWE-377] Insecure Temporary File.

(predictable-tmp-file-bash)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@k8s/createLKE_install_PMM_HA.sh` around lines 206 - 210, The current kubectl
get pods and kubectl get events commands collect only pod metadata and events,
not actual container logs as indicated by the section header. Add kubectl logs
commands that capture the actual container output from PMM pods to the
/tmp/helm-debug directory. Use the --all-containers=true flag to handle pods
with multiple containers, and apply the || true pattern to each logs command to
maintain the script's resilience when log collection encounters errors.

Comment on lines +217 to +221
echo "PMM PAssword : $PMM_PW"
echo "Clickhouse password: $CH_PW"
echo "Postgres password: $PG_PW"
echo "Grafana password: $GF_PW"
echo "VM password: $VM_PW"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

cat -n k8s/createLKE_install_PMM_HA.sh | sed -n '215,225p'

Repository: percona/pmm-qa

Length of output: 419


🏁 Script executed:

# Check if these are the only places where passwords are echoed in the script
rg -n "echo.*PW" k8s/createLKE_install_PMM_HA.sh

Repository: percona/pmm-qa

Length of output: 329


🏁 Script executed:

# Verify the password variables are generated or set in the script
rg -n "PMM_PW|CH_PW|PG_PW|GF_PW|VM_PW" k8s/createLKE_install_PMM_HA.sh | head -20

Repository: percona/pmm-qa

Length of output: 907


🏁 Script executed:

# Check if there's any conditional logic around printing these credentials
sed -n '210,225p' k8s/createLKE_install_PMM_HA.sh

Repository: percona/pmm-qa

Length of output: 586


🏁 Script executed:

# Check the full script structure to understand if the echo is necessary
# Look for any flags or parameters that might control output
rg -n "#!/bin|set -" k8s/createLKE_install_PMM_HA.sh | head -5

Repository: percona/pmm-qa

Length of output: 186


🏁 Script executed:

# Check if there's any documentation or comments explaining why credentials are printed
sed -n '200,230p' k8s/createLKE_install_PMM_HA.sh

Repository: percona/pmm-qa

Length of output: 1034


Sensitive Data Exposure (CWE-532): Insertion of Sensitive Information into Log File

Reachability: Internal

Remove credential output from stdout. Lines 217–221 print passwords for PMM, ClickHouse, Postgres, Grafana, and VM to stdout. These credentials are correctly stored in Kubernetes secrets but must not be echoed where CI logs, shell history, or terminal captures retain them. Remove these echo lines. If an operator summary is needed, write only the endpoint and deployment status.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@k8s/createLKE_install_PMM_HA.sh` around lines 217 - 221, Remove the
password-printing echo statements for PMM, ClickHouse, Postgres, Grafana, and VM
credentials from the script. Keep the Kubernetes secret storage unchanged; if
the surrounding summary is retained, limit it to non-sensitive endpoint or
deployment-status information.

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.

1 participant