-
Notifications
You must be signed in to change notification settings - Fork 12
Address review findings from dev environment PR#21 #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
b3f8525
93f17dd
ed8d5e4
b4f0f93
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| #!/bin/bash | ||
| # Creates a NodeHealthCheck CR that references an available remediator. | ||
| # Auto-detects deployed remediator templates (SNR, FAR, MDR) and uses the first found. | ||
| # Usage: create-nhc.sh [--duration <seconds>] | ||
| # Usage: create-nhc.sh [--duration <duration>] (e.g. 300s, 5m, 1h) | ||
|
|
||
| set -euo pipefail | ||
|
|
||
|
|
@@ -16,6 +16,10 @@ NHC_UNHEALTHY_DURATION="${NHC_UNHEALTHY_DURATION:-300s}" | |
| while [[ $# -gt 0 ]]; do | ||
| case $1 in | ||
| --duration) | ||
| if [[ $# -lt 2 ]]; then | ||
| echo "Error: --duration requires a value (e.g. 300s, 5m, 1h)" | ||
| exit 1 | ||
| fi | ||
| NHC_UNHEALTHY_DURATION="$2" | ||
| shift 2 | ||
| ;; | ||
|
|
@@ -28,6 +32,12 @@ while [[ $# -gt 0 ]]; do | |
| esac | ||
| done | ||
|
|
||
| # Validate duration format | ||
| if ! [[ "${NHC_UNHEALTHY_DURATION}" =~ ^[0-9]+(s|m|h)$ ]]; then | ||
| echo "Error: NHC_UNHEALTHY_DURATION must be a duration (e.g. 300s, 5m, 1h), got: '${NHC_UNHEALTHY_DURATION}'" | ||
| exit 1 | ||
| fi | ||
|
Comment on lines
+35
to
+39
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
rg -n -C 4 \
'NHC_UNHEALTHY_DURATION|unhealthyConditions|duration:' \
--glob '*.sh' --glob '*.yaml' --glob '*.yml' --glob '*.md' .Repository: medik8s/tools Length of output: 3487 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- relevant repository files ---'
git ls-files | rg '(^|/)(create-nhc\.sh|README\.md|.*nhc.*|.*nodehealth.*|.*crd.*)$' | head -200
printf '%s\n' '--- create-nhc.sh ---'
cat -n dev/create-nhc.sh | sed -n '1,125p'
printf '%s\n' '--- duration and NHC references ---'
rg -n -C 3 \
'unhealthyConditions|UnhealthyCondition|duration:|NHC_UNHEALTHY_DURATION|NodeHealthCheck' \
--glob '!vendor/**' --glob '!node_modules/**' .Repository: medik8s/tools Length of output: 22224 🌐 Web query:
💡 Result: In the NodeHealthCheck (NHC) custom resource used by the medik8s operator, the duration field within the unhealthyConditions list specifies the time a node condition must persist before the node is considered unhealthy and remediation is triggered [1][2][3]. The accepted format for the duration field is a string of decimal numbers followed by an optional fraction and a unit suffix [2][3]. Supported time units are "ns", "us" (or "µs"), "ms", "s", "m", and "h" [2][3]. Examples of valid duration values include "300s", "300ms", "1.5h", and "2h45m" [1][2][3]. The validation for this field is enforced by the pattern: ^([0-9]+(.[0-9]+)?(ns|us|µs|ms|s|m|h))+$ [2][3]. While the Self Node Remediation operator handles the actual rebooting of unhealthy nodes [4], it is configured via its own separate CR, SelfNodeRemediationConfig, which contains settings such as watchdog paths and safety timeouts, but does not use the duration field found in the NodeHealthCheck CR [5]. The NodeHealthCheck CR's unhealthyConditions, including the duration, remain the primary configuration for detecting node failure and initiating remediation [6][7][8]. Citations:
🏁 Script executed: #!/bin/bash
set -euo pipefail
python3 - <<'PY'
import re
import urllib.request
urls = {
"api": "https://raw.githubusercontent.com/medik8s/node-healthcheck-operator/d4a4253d/api/v1alpha1/nodehealthcheck_types.go",
"crd": "https://raw.githubusercontent.com/medik8s/node-healthcheck-operator/main/config/crd/bases/remediation.medik8s.io_nodehealthchecks.yaml",
"docs": "https://raw.githubusercontent.com/medik8s/node-healthcheck-operator/main/docs/configuration.md",
}
for name, url in urls.items():
try:
text = urllib.request.urlopen(url, timeout=10).read().decode()
except Exception as exc:
print(f"{name}: fetch failed: {exc}")
continue
print(f"--- {name} ---")
for i, line in enumerate(text.splitlines(), 1):
if re.search(r"duration|pattern:|unhealthyConditions", line, re.I):
start = max(1, i - 2)
end = min(len(text.splitlines()), i + 3)
lines = text.splitlines()
for n in range(start, end + 1):
print(f"{n}: {lines[n-1]}")
print()
script_pattern = re.compile(r"^[0-9]+(s|m|h)$")
contract_pattern = re.compile(
r"^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$"
)
values = ["300s", "1h30m", "500ms", "1.5h", "2h45m", "1µs"]
print("--- sample comparison ---")
for value in values:
print(
f"{value}: script={bool(script_pattern.fullmatch(value))}, "
f"contract={bool(contract_pattern.fullmatch(value))}"
)
PYRepository: medik8s/tools Length of output: 845 🏁 Script executed: #!/bin/bash
set -euo pipefail
for spec in \
"api https://raw.githubusercontent.com/medik8s/node-healthcheck-operator/d4a4253d/api/v1alpha1/nodehealthcheck_types.go" \
"crd https://raw.githubusercontent.com/medik8s/node-healthcheck-operator/main/config/crd/bases/remediation.medik8s.io_nodehealthchecks.yaml" \
"docs https://raw.githubusercontent.com/medik8s/node-healthcheck-operator/main/docs/configuration.md"
do
name="${spec%% *}"
url="${spec#* }"
printf '%s\n' "--- ${name} ---"
curl -fsSLk --max-time 15 "$url" |
rg -n -C 3 'duration|pattern:|unhealthyConditions' || true
doneRepository: medik8s/tools Length of output: 13841 Use the NHC duration grammar. The NHC 🤖 Prompt for AI Agents |
||
|
|
||
| # Check if the NHC CRD exists | ||
| if ! ${KUBECTL} get crd nodehealthchecks.remediation.medik8s.io &>/dev/null; then | ||
| echo "Error: NodeHealthCheck CRD not found. Deploy NHC first (make dev-deploy from the NHC directory)." | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -52,7 +52,7 @@ TTL_SH_TTL ?= 2h | |||||||||||||||||
| ifeq ($(DEV_REGISTRY),local) | ||||||||||||||||||
| DEV_IMG ?= localhost:5000/medik8s/$(OPERATOR_NAME):dev | ||||||||||||||||||
| else | ||||||||||||||||||
| DEV_IMG ?= ttl.sh/medik8s-$(OPERATOR_NAME)-$(shell echo $$USER | head -c 8):$(TTL_SH_TTL) | ||||||||||||||||||
| DEV_IMG ?= ttl.sh/medik8s-$(OPERATOR_NAME)-$(shell head -c 32 /dev/urandom | base64 | tr -dc 'a-z0-9' | head -c 8):$(TTL_SH_TTL) | ||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
tmpdir=$(mktemp -d)
trap 'rm -rf "$tmpdir"' EXIT
cat >"$tmpdir/Makefile" <<'EOF'
DEV_IMG ?= prefix-$(shell od -An -N8 -tx1 /dev/urandom | tr -d '[:space:]')
all:
`@printf` '%s\n' "$(DEV_IMG)" "$(DEV_IMG)"
EOF
mapfile -t tags < <(make -f "$tmpdir/Makefile" --no-print-directory)
test "${tags[0]}" = "${tags[1]}"Repository: medik8s/tools Length of output: 243 🏁 Script executed: #!/bin/bash
set -u
printf '%s\n' '--- dev/dev.mk lines 45-65 ---'
nl -ba dev/dev.mk | sed -n '45,65p'
printf '%s\n' '--- DEV_IMG references and assignments ---'
rg -n -C 2 'DEV_IMG|dev-build|docker build|docker push|podman build|podman push' dev/dev.mk
printf '%s\n' '--- available make implementations ---'
command -v make || true
command -v gmake || trueRepository: medik8s/tools Length of output: 3605 🏁 Script executed: #!/bin/bash
set -u
python3 - <<'PY'
from pathlib import Path
import re
path = Path("dev/dev.mk")
text = path.read_text()
lines = text.splitlines()
assignments = [
(i + 1, line)
for i, line in enumerate(lines)
if re.search(r"\bDEV_IMG\s*\?=", line)
]
references = [
(i + 1, line.count("$(DEV_IMG)"), line.strip())
for i, line in enumerate(lines)
if "$(DEV_IMG)" in line
]
print("DEV_IMG ?= assignments:")
for item in assignments:
print(item)
print("DEV_IMG references:")
for item in references:
print(item)
print("recipe references:", sum(count for _, count, _ in references))
# Model the relevant GNU make expansion rule: a recursively expanded
# variable stores the RHS and expands shell functions at each reference.
suffix_calls = 0
def expand_dev_img():
global suffix_calls
suffix_calls += 1
return f"ttl.sh/medik8s-name-random{suffix_calls}:2h"
first_build = expand_dev_img()
first_push = expand_dev_img()
print("recursive expansion sample:", first_build, first_push)
print("sample values differ:", first_build != first_push)
PYRepository: medik8s/tools Length of output: 1243 🌐 Web query:
💡 Result: In GNU make, the?= operator assigns a value to a variable only if that variable has not been previously defined [1][2]. Variables defined with?= are of the recursively expanded flavor [2]. When you use the shell function within a recursively expanded variable (including those defined via?=), the shell command is executed every time the variable is expanded [3][4]. Key behaviors to note: 1. Timing of Expansion: Because recursively expanded variables are not expanded until they are used, any shell function contained within them is also not executed until that moment [3][4]. If you reference the variable multiple times, the shell command will be spawned and executed each time [3]. 2. Performance and Side Effects: This behavior can lead to significant performance overhead if the shell command is resource-intensive or slow [3]. Furthermore, because the expansion timing can be difficult to control, it often causes unpredictable results or unintended side effects, especially if the command modifies the environment or relies on external state that changes during the make process [3]. 3. Comparison with Simply Expanded Variables: To execute a shell command only once at the time of assignment, you should use the simply expanded assignment operator (:=) instead of = or?= [3][2]. For example: FOO:= Citations:
Freeze the generated When Add 🤖 Prompt for AI Agents |
||||||||||||||||||
| endif | ||||||||||||||||||
|
|
||||||||||||||||||
| # Detect kubectl or oc | ||||||||||||||||||
|
|
@@ -127,12 +127,13 @@ ifeq ($(DEV_REGISTRY),local) | |||||||||||||||||
| fi; \ | ||||||||||||||||||
| done; \ | ||||||||||||||||||
| restore() { for f in $$patched; do sed -i.bak 's/imagePullPolicy: IfNotPresent/imagePullPolicy: Always/' "$$f" && rm -f "$$f.bak"; done; }; \ | ||||||||||||||||||
| trap restore EXIT; \ | ||||||||||||||||||
| TMPTAR=$$(mktemp /tmp/dev-image-XXXXXX.tar); \ | ||||||||||||||||||
| cleanup() { rm -f "$$TMPTAR"; restore; }; \ | ||||||||||||||||||
| trap cleanup EXIT; \ | ||||||||||||||||||
|
Comment on lines
+130
to
+132
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win Restore the exact files that this target patches. The exit cleanup calls 🤖 Prompt for AI Agents |
||||||||||||||||||
| $(CONTAINER_TOOL) build -t $(DEV_IMG) . && \ | ||||||||||||||||||
| $(CONTAINER_TOOL) save -o /tmp/dev-image-$(OPERATOR_NAME).tar $(DEV_IMG) && \ | ||||||||||||||||||
| $(CONTAINER_TOOL) save -o "$$TMPTAR" $(DEV_IMG) && \ | ||||||||||||||||||
| KIND_EXPERIMENTAL_PROVIDER=$(if $(filter podman,$(CONTAINER_TOOL)),podman,docker) \ | ||||||||||||||||||
| kind load image-archive /tmp/dev-image-$(OPERATOR_NAME).tar --name $(MEDIK8S_CLUSTER_NAME) && \ | ||||||||||||||||||
| rm -f /tmp/dev-image-$(OPERATOR_NAME).tar | ||||||||||||||||||
| kind load image-archive "$$TMPTAR" --name $(MEDIK8S_CLUSTER_NAME) | ||||||||||||||||||
| else | ||||||||||||||||||
| $(CONTAINER_TOOL) build -t $(DEV_IMG) . | ||||||||||||||||||
| $(CONTAINER_TOOL) push $(DEV_IMG) | ||||||||||||||||||
|
|
@@ -149,9 +150,9 @@ dev-deploy: dev-build install $(if $(ENVSUBST),envsubst) ## Build, load image, i | |||||||||||||||||
| cd config/manager && $(KUSTOMIZE) edit set image controller=$(DEV_IMG) && cd ../.. && \ | ||||||||||||||||||
| ENVSUBST_BIN="$(ENVSUBST)"; \ | ||||||||||||||||||
| if [ -n "$$ENVSUBST_BIN" ] && [ -x "$$ENVSUBST_BIN" ]; then \ | ||||||||||||||||||
| export IMG=$(DEV_IMG) && $(KUSTOMIZE) build config/default 2>&1 | grep -v "Warning: 'commonLabels'" | $$ENVSUBST_BIN | $(KUBECTL) apply -f -; \ | ||||||||||||||||||
| export IMG=$(DEV_IMG) && $(KUSTOMIZE) build config/default 2> >(grep -v "Warning: 'commonLabels'" >&2) | $$ENVSUBST_BIN | $(KUBECTL) apply -f -; \ | ||||||||||||||||||
| else \ | ||||||||||||||||||
| $(KUSTOMIZE) build config/default 2>&1 | grep -v "Warning: 'commonLabels'" | $(KUBECTL) apply -f -; \ | ||||||||||||||||||
| $(KUSTOMIZE) build config/default 2> >(grep -v "Warning: 'commonLabels'" >&2) | $(KUBECTL) apply -f -; \ | ||||||||||||||||||
|
Comment on lines
+153
to
+155
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
rg -n -C 4 \
'(^SHELL|SHELLFLAGS|pipefail|KUSTOMIZE.*build|commonLabels)' \
--glob 'Makefile' --glob '*.mk' .Repository: medik8s/tools Length of output: 1969 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- dev/dev.mk context ---'
sed -n '1,30p;120,175p;190,215p' dev/dev.mk
printf '%s\n' '--- makefile includes and shell settings ---'
rg -n -C 3 \
'(^SHELL|SHELLFLAGS|include .*dev|dev\.mk|\.DEFAULT_GOAL)' \
--glob 'Makefile' --glob '*.mk' .
printf '%s\n' '--- target and recipe metadata ---'
rg -n -C 5 \
'^[[:alnum:]_.-]+:.*(dev|deploy)|^dev-[[:alnum:]_.-]+:|KUSTOMIZE[[:space:]]*[:?+]?=' \
dev/dev.mk Makefile --glob 'Makefile' --glob '*.mk' 2>/dev/null || trueRepository: medik8s/tools Length of output: 15944 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- repository Makefiles ---'
git ls-files '*Makefile' '*.mk' | sort
printf '%s\n' '--- shell declarations and dev.mk inclusion ---'
rg -n -C 2 \
'(^SHELL[[:space:]]*[:?+]?=|SHELLFLAGS|dev/dev\.mk|dev\.mk)' \
--glob 'Makefile' --glob '*.mk' . || true
printf '%s\n' '--- available shell implementations ---'
command -v bash || true
command -v sh || true
command -v dash || true
printf '%s\n' '--- pipeline status probe ---'
bash -c 'set +o pipefail; (printf "partial\n"; exit 7) | cat; printf "bash-no-pipefail=%s\n" "$?"'
bash -c 'set -o pipefail; (printf "partial\n"; exit 7) | cat; printf "bash-pipefail=%s\n" "$?"'
if command -v dash >/dev/null 2>&1; then
dash -c '(printf "partial\n"; exit 7) | cat; printf "dash=%s\n" "$?"'
fi
printf '%s\n' '--- process-substitution probe ---'
bash -c 'printf ok 2> >(grep -v warning >&2); printf "bash-process-substitution=%s\n" "$?"'
if command -v dash >/dev/null 2>&1; then
dash -c 'printf ok 2> >(grep -v warning >&2)' >/tmp/dev-mk-dash.stdout 2>/tmp/dev-mk-dash.stderr || dash_status=$?
printf 'dash-process-substitution=%s\n' "${dash_status:-0}"
cat /tmp/dev-mk-dash.stderr
rm -f /tmp/dev-mk-dash.stdout /tmp/dev-mk-dash.stderr
fiRepository: medik8s/tools Length of output: 1062 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- shell identity ---'
ls -l /usr/bin/sh
/usr/bin/sh -c 'printf "shell=%s\n" "$0"; set -o | grep -E "^(pipefail|posix)" || true'
printf '%s\n' '--- make availability and default recipe shell ---'
if command -v make >/dev/null 2>&1; then
make --version | head -1
printf '%s\n' \
'all:' \
' `@printf` "make-shell=%s\\n" "$$0"; set -o | grep -E "^(pipefail|posix)" || true' \
| make -f - --no-print-directory
else
printf '%s\n' 'make is unavailable'
fi
printf '%s\n' '--- make recipe with the reviewed pipeline ---'
if command -v make >/dev/null 2>&1; then
printf '%s\n' \
'all:' \
' @ (printf "partial\\n"; exit 7) | cat; printf "recipe-status=%s\\n" "$$?"' \
| make -f - --no-print-directory
fi
printf '%s\n' '--- make recipe with process substitution under its default shell ---'
if command -v make >/dev/null 2>&1; then
set +e
printf '%s\n' \
'all:' \
' `@printf` ok 2> >(grep -v warning >&2)' \
| make -f - --no-print-directory >/tmp/dev-mk.stdout 2>/tmp/dev-mk.stderr
status=$?
set -e
printf 'recipe-process-substitution-status=%s\n' "$status"
cat /tmp/dev-mk.stderr
rm -f /tmp/dev-mk.stdout /tmp/dev-mk.stderr
fiRepository: medik8s/tools Length of output: 477 Propagate Kustomize failures through the pipeline. Without 🤖 Prompt for AI Agents |
||||||||||||||||||
| fi | ||||||||||||||||||
| @# Detect the operator namespace from kustomization files (reliable, no cluster query needed). | ||||||||||||||||||
| @# The namespace may be in config/default/ or in a component/patch kustomization.yaml. | ||||||||||||||||||
|
|
@@ -302,7 +303,7 @@ dev-describe: ## Full summary of all medik8s resources (nodes, pods, CRs, leases | |||||||||||||||||
|
|
||||||||||||||||||
| .PHONY: dev-shell | ||||||||||||||||||
| dev-shell: ## Open a shell on a Kind node (use NODE=<name>, default: first worker) | ||||||||||||||||||
| @NODES=$$(kind get nodes --name $(MEDIK8S_CLUSTER_NAME) 2>/dev/null); \ | ||||||||||||||||||
| @NODES=$$(KIND_EXPERIMENTAL_PROVIDER=$(CONTAINER_TOOL) kind get nodes --name $(MEDIK8S_CLUSTER_NAME) 2>/dev/null); \ | ||||||||||||||||||
| if [ -z "$$NODES" ]; then \ | ||||||||||||||||||
| NODES=$$($(KUBECTL) get nodes --no-headers -o custom-columns=NAME:.metadata.name 2>/dev/null); \ | ||||||||||||||||||
| fi; \ | ||||||||||||||||||
|
|
@@ -317,6 +318,10 @@ dev-shell: ## Open a shell on a Kind node (use NODE=<name>, default: first worke | |||||||||||||||||
| if [ -z "$$TARGET" ]; then \ | ||||||||||||||||||
| TARGET=$$(echo "$$NODES" | head -1); \ | ||||||||||||||||||
| fi; \ | ||||||||||||||||||
| if ! echo "$$NODES" | grep -qx "$$TARGET"; then \ | ||||||||||||||||||
| echo "Error: '$$TARGET' is not a node in the cluster. Available: $$(echo $$NODES | tr '\n' ' ')"; \ | ||||||||||||||||||
| exit 1; \ | ||||||||||||||||||
| fi; \ | ||||||||||||||||||
|
Comment on lines
+321
to
+324
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Use fixed-string matching for
Proposed fix- if ! echo "$$NODES" | grep -qx "$$TARGET"; then \
+ if ! printf '%s\n' "$$NODES" | grep -Fqx -- "$$TARGET"; then \📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
| echo "Opening shell on $$TARGET..."; \ | ||||||||||||||||||
| echo " (type 'exit' to return)"; \ | ||||||||||||||||||
| $(CONTAINER_TOOL) exec -it "$$TARGET" bash | ||||||||||||||||||
|
|
||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -75,8 +75,8 @@ ${KUBECTL} wait --for=condition=Ready certificate/serving-cert -n "${NAMESPACE}" | |||||
| # Annotate webhook configurations for CA injection | ||||||
| for wh_type in mutatingwebhookconfigurations validatingwebhookconfigurations; do | ||||||
| for wh in $(${KUBECTL} get "${wh_type}" -o name 2>/dev/null); do | ||||||
| # Only annotate webhooks that reference services in our namespace | ||||||
| if ${KUBECTL} get "${wh}" -o yaml 2>/dev/null | grep -q "namespace: ${NAMESPACE}"; then | ||||||
| # Only annotate webhooks whose clientConfig targets our namespace | ||||||
| if ${KUBECTL} get "${wh}" -o jsonpath='{.webhooks[*].clientConfig.service.namespace}' 2>/dev/null | grep -qw "${NAMESPACE}"; then | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Use exact namespace matching.
Emit one namespace per line and use fixed exact-line matching. Proposed fix-if ${KUBECTL} get "${wh}" -o jsonpath='{.webhooks[*].clientConfig.service.namespace}' 2>/dev/null | grep -qw "${NAMESPACE}"; then
+if ${KUBECTL} get "${wh}" -o jsonpath='{range .webhooks[*].clientConfig.service.namespace}{.}{"\n"}{end}' 2>/dev/null | grep -Fxq -- "${NAMESPACE}"; then📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
| ${KUBECTL} annotate "${wh}" cert-manager.io/inject-ca-from="${NAMESPACE}/serving-cert" --overwrite 2>/dev/null || true | ||||||
| fi | ||||||
| done | ||||||
|
|
@@ -86,7 +86,9 @@ done | |||||
| if ${KUBECTL} get deployment "${DEPLOY_NAME}" -n "${NAMESPACE}" -o jsonpath='{.spec.template.spec.volumes[*].name}' 2>/dev/null | grep -q cert; then | ||||||
| echo " Deployment already has TLS volume mount — skipping patch." | ||||||
| else | ||||||
| echo " Patching deployment to mount webhook TLS secret..." | ||||||
| CONTAINER_NAME=$(${KUBECTL} get deployment "${DEPLOY_NAME}" -n "${NAMESPACE}" \ | ||||||
| -o jsonpath='{.spec.template.spec.containers[0].name}') | ||||||
| echo " Patching deployment to mount webhook TLS secret (container: ${CONTAINER_NAME})..." | ||||||
| ${KUBECTL} patch deployment "${DEPLOY_NAME}" -n "${NAMESPACE}" --type=strategic -p='{ | ||||||
| "spec": { | ||||||
| "template": { | ||||||
|
|
@@ -99,7 +101,7 @@ else | |||||
| } | ||||||
| }], | ||||||
| "containers": [{ | ||||||
| "name": "manager", | ||||||
| "name": "'"${CONTAINER_NAME}"'", | ||||||
| "volumeMounts": [{ | ||||||
| "name": "cert", | ||||||
| "mountPath": "/tmp/k8s-webhook-server/serving-certs", | ||||||
|
|
||||||
There was a problem hiding this comment.
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:
Repository: medik8s/tools
Length of output: 1395
🌐 Web query:
GitHub Actions workflow permissions unspecified permissions default GITHUB_TOKEN contents read documentation persist-credentials checkout💡 Result:
In GitHub Actions, the GITHUB_TOKEN and the actions/checkout action interact through specific permission models and configuration settings. GITHUB_TOKEN Default Permissions The default permissions for the GITHUB_TOKEN are determined by settings at the repository, organization, or enterprise level [1][2]. - Repository Settings: Administrators can configure the GITHUB_TOKEN to use either permissive or restricted access [1]. - Restricted Default: When set to restricted (often the default for new repositories), the GITHUB_TOKEN is granted read-only access to contents and packages [1]. - Explicit Configuration: Best practice is to explicitly define the permissions for a workflow or job using the permissions key in your workflow file to follow the principle of least privilege [3][2][4]. If you specify permissions for any scope, all unspecified scopes are set to none [2]. actions/checkout and persist-credentials The actions/checkout action uses the GITHUB_TOKEN by default to perform git operations [5][6]. - persist-credentials Setting: This input determines whether the action configures the git credential helper to use the provided token (or SSH key) in the local git config [5][6][7]. - Default Behavior: As of current versions, persist-credentials defaults to true [7]. When set to true, the token is persisted in the local git configuration to enable subsequent authenticated git commands during the job [5][6]. - Security Note: While persist-credentials=true is the default, the token is cleaned up after the job finishes [5][6]. Recent versions of actions/checkout have improved security by storing these credentials in a separate file under the runner's temporary directory rather than directly in.git/config, which helps mitigate risks associated with token exposure [5][6]. To adhere to security best practices, it is recommended to explicitly set permissions in your workflow files and evaluate whether persist-credentials needs to be set to false if your specific use case does not require the action to handle authentication for subsequent git commands [3][4][5].
Citations:
🏁 Script executed:
Repository: medik8s/tools
Length of output: 546
Add explicit least-privilege permissions.
This workflow needs only repository read access. Without a
permissionsblock,GITHUB_TOKENuses repository, organization, or enterprise defaults.persist-credentials: falsedoes not limit API permissions. Addcontents: readat workflow or job scope.🧰 Tools
🪛 zizmor (1.29.0)
[warning] 11-24: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block
(excessive-permissions)
🤖 Prompt for AI Agents
Source: Linters/SAST tools