feat(edge-cve): add Black CVE investigation plugin with govulncheck#232
feat(edge-cve): add Black CVE investigation plugin with govulncheck#232eggfoobar wants to merge 4 commits into
Conversation
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: eggfoobar The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
WalkthroughThe PR adds and registers the ChangesEdge CVE plugin workflow
Estimated code review effort: 5 (Critical) | ~120 minutes ✨ Finishing Touches🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Actionable comments posted: 15
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
plugins/edge-cve/k8s/namespace.yaml (1)
1-7: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winMissing NetworkPolicy for
edge-cve-scansnamespace.No NetworkPolicy is defined anywhere in the manifests. Scan Jobs clone and build third-party Go repos; without network isolation, pods in this namespace have unrestricted egress/ingress to the rest of the cluster.
As per path instructions for Kubernetes/OpenShift manifests: "NetworkPolicy defined for the namespace."
Example default-deny NetworkPolicy
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny namespace: edge-cve-scans spec: podSelector: {} policyTypes: - Ingress - Egress egress: - {} # tighten to required egress (e.g. git remotes, k8s API) as needed🤖 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 `@plugins/edge-cve/k8s/namespace.yaml` around lines 1 - 7, Add a Kubernetes NetworkPolicy for the edge-cve-scans Namespace, using the namespace name and an empty podSelector to cover all pods. Configure default-deny ingress and egress policy types, while preserving only the explicitly required egress destinations for scan Jobs if those requirements are defined in the manifests.Source: Path instructions
plugins/edge-cve/scripts/test_cve_extract.py (1)
1-112: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winMissing test coverage for
is_private_ticket.This function gates redaction of CVE IDs/summaries for restricted tickets in HTML reports — a privacy-sensitive path — but has no positive/negative test here (only
security_levelmatch and label match paths are exercised elsewhere in the codebase, if at all). Per CONTRIBUTING.md: "ensure...validation/parsing logic has positive/negative test coverage" for this plugin's Jira parsing pipeline.def test_is_private_ticket_security_level(self): self.assertTrue(is_private_ticket({"security_level": "Private", "labels": []})) def test_is_private_ticket_label(self): self.assertTrue(is_private_ticket({"security_level": "", "labels": ["Private-CVE"]})) def test_is_private_ticket_public(self): self.assertFalse(is_private_ticket({"security_level": "Restricted", "labels": ["cve"]}))🤖 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 `@plugins/edge-cve/scripts/test_cve_extract.py` around lines 1 - 112, Add is_private_ticket to the imported CVE extraction helpers and extend CveExtractTests with positive coverage for a Private security_level and Private-CVE label, plus negative coverage for a non-private ticket. Keep the assertions focused on the boolean result for each case.
🟡 Minor comments (9)
plugins/edge-cve/README.md-49-51 (1)
49-51: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winUse Markdown link syntax for the saved-filter URL.
The bare URL is not customer-friendly and may violate the repository’s Markdown lint configuration. Render it as a descriptive Markdown link.
Per CONTRIBUTING.md, Markdown must pass markdownlint.
🤖 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 `@plugins/edge-cve/README.md` around lines 49 - 51, Update the saved-filter reference in the README to use descriptive Markdown link syntax instead of a bare URL, preserving the existing destination and ensuring it complies with repository markdownlint rules.Source: Coding guidelines
plugins/edge-cve/README.md-15-15 (1)
15-15: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winMake the token example valid shell.
export JIRA_API_TOKEN=<token>is parsed as shell redirection syntax rather than a value assignment. Use a quoted placeholder such asexport JIRA_API_TOKEN='replace-with-token'.🤖 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 `@plugins/edge-cve/README.md` at line 15, Update the JIRA_API_TOKEN example in the README to use a quoted placeholder value, ensuring the export command is valid shell syntax and does not interpret the placeholder as redirection.plugins/edge-cve/README.md-107-111 (1)
107-111: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick winInstall from the requirements file, and pin it there first.
pip install requestsbypassesplugins/edge-cve/requirements.txt; update the README topython3 -m pip install -r plugins/edge-cve/requirements.txt, and changerequests>=2.28.0to an exact pin. Per CONTRIBUTING.md: “production dependencies must be pinned exactly.”🤖 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 `@plugins/edge-cve/README.md` around lines 107 - 111, Update the Python dependencies section in the README to install via the requirements file using python3 -m pip install -r plugins/edge-cve/requirements.txt, and change the requests dependency in plugins/edge-cve/requirements.txt from the minimum version constraint to an exact version pin.Source: Path instructions
plugins/edge-cve/config/component-repos.json-44-47 (1)
44-47: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winTrim trailing punctuation from repo slugs. In
plugins/edge-cve/config/component-repos.json:44-47, these patterns can capture closing),],,, or.from prose, andextract_repo_urls()forwards that intoslugunchanged. That produces invalid targets likeopenshift/microshift).Make the match boundary-aware or strip trailing punctuation before building the slug.🤖 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 `@plugins/edge-cve/config/component-repos.json` around lines 44 - 47, The repo_url_patterns entries currently allow trailing prose punctuation into the captured repo name. Update the repository URL extraction flow, including extract_repo_urls(), so captured slugs exclude closing ), ], commas, and periods before the slug is constructed, while preserving valid repository characters and existing URL matching behavior.plugins/edge-cve/k8s/rbac.yaml-12-15 (1)
12-15: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick winNarrow the ConfigMap RBAC
Per CONTRIBUTING.md: “RBAC: least privilege.” This job only creates and patch-merges ConfigMaps, so
get,list, andupdatecan be removed fromplugins/edge-cve/k8s/rbac.yaml:15.🤖 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 `@plugins/edge-cve/k8s/rbac.yaml` around lines 12 - 15, Update the ConfigMap rule under resources ["configmaps"] to remove the unnecessary "get", "list", and "update" verbs, retaining only "create" and "patch" for the job’s required operations.Source: Path instructions
plugins/edge-cve/scripts/build_scan_targets.py-21-27 (1)
21-27: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winTruncated slug-based
target_idrisks collisions across distinct repo/ref pairs.
slugify()lowercases, replaces non-alnum with-, and truncates to 50 chars;target_idconcatenates two truncated slugs. Two different(repo_slug, git_ref)pairs that normalize/truncate to the same string (e.g., long slugs sharing a 50-char prefix, or refs differing only in characters that both become-) would collide intargets_map(line 47), silently merging unrelated CVE/ticket metadata into one scan target. Downstream,run_govulncheck_jobs.shtreats this id as the unique key for job addressing, so a collision could also cause one scan job to be skipped or overwritten by another.Append a short content hash to guarantee uniqueness regardless of truncation.
🔧 Suggested fix
+import hashlib + def slugify(value: str) -> str: return re.sub(r"[^a-z0-9]+", "-", value.lower()).strip("-")[:50] def target_id(repo_slug: str, git_ref: str) -> str: - return f"{slugify(repo_slug)}--{slugify(git_ref)}" + digest = hashlib.sha256(f"{repo_slug}@{git_ref}".encode()).hexdigest()[:8] + return f"{slugify(repo_slug)}--{slugify(git_ref)}--{digest}"🤖 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 `@plugins/edge-cve/scripts/build_scan_targets.py` around lines 21 - 27, Update target_id to append a short deterministic content hash derived from the original repo_slug and git_ref, while retaining the existing slugified components for readability. Ensure the hash input distinguishes the two values unambiguously and is included in every returned ID so truncation or normalization cannot cause collisions in targets_map or downstream job addressing.plugins/edge-cve/scripts/cve-investigator.sh-9-11 (1)
9-11: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winUsage text/header comment omit
--repo-slugand--no-prune.
cmd_check_repoparses--repo-slug(line 87) and--no-prune(line 97), but neither the top-of-file comment norusage()documents them, which will confuse users of--help.Also applies to: 145-147
🤖 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 `@plugins/edge-cve/scripts/cve-investigator.sh` around lines 9 - 11, Update the cve-investigator.sh usage header and usage() output for cmd_check_repo to document both supported options, --repo-slug and --no-prune, alongside the existing repository arguments. Keep the descriptions consistent with their parsed behavior and ensure both help locations expose them.plugins/edge-cve/scripts/cve-investigator.sh-1-1 (1)
1-1: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winShebang must be
#!/usr/bin/bashper coding guidelines.This file uses
#!/usr/bin/env bash.🛠️ Proposed fix
-#!/usr/bin/env bash +#!/usr/bin/bashAs per coding guidelines,
**/*.sh: "Shebang must be#!/usr/bin/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 `@plugins/edge-cve/scripts/cve-investigator.sh` at line 1, Update the shebang at the start of the cve-investigator.sh script from the env-based form to the required direct Bash path, using exactly #!/usr/bin/bash.Source: Coding guidelines
plugins/edge-cve/scripts/run_single_repo_scan.sh-82-84 (1)
82-84: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winHandle SSH remote URLs in
REPO_SLUGfallback.git@github.com:org/repo.gitbecomesrepo, so omitting--repo-slugdrops the org segment for SSH remotes. Normalizeuser@host:owner/repofirst, or use a proper parser here.🤖 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 `@plugins/edge-cve/scripts/run_single_repo_scan.sh` around lines 82 - 84, Update the REPO_SLUG fallback normalization to support SSH remotes such as git@github.com:owner/repo.git, preserving the owner/repository path while removing the SSH host prefix and optional .git suffix. Keep the existing HTTPS URL handling intact and apply the change within the REPO_SLUG assignment block.
🧹 Nitpick comments (12)
plugins/edge-cve/k8s/govulncheck-job.yaml.template (1)
24-24: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winConsider pinning the base image by digest.
registry.redhat.io/ubi9/go-toolset:1.23is pinned by tag only; the tag can be re-pointed to a different underlying image over time.🤖 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 `@plugins/edge-cve/k8s/govulncheck-job.yaml.template` at line 24, Update the image reference in the govulncheck job template from the mutable registry.redhat.io/ubi9/go-toolset:1.23 tag to the corresponding immutable digest-pinned reference, preserving the intended Go toolset version.Source: Path instructions
plugins/edge-cve/requirements.txt (1)
1-1: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winPin an exact
requestsversion.
requests>=2.28.0allows any newer release to be installed, which conflicts with the supply-chain guideline to pin exact versions for reproducible, vetted builds.As per path instructions,
**/{requirements*.txt,...}: "Pin exact versions; verify hashes where supported."Proposed fix
-requests>=2.28.0 +requests==2.32.3🤖 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 `@plugins/edge-cve/requirements.txt` at line 1, Update the requests dependency declaration in requirements.txt from a minimum-version constraint to an exact, vetted version pin, following the repository’s supply-chain guidance; preserve the existing dependency name and verify or add its hash if supported by the project’s requirements format.Source: Path instructions
plugins/edge-cve/scripts/generate_report.py (1)
29-35: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueScan-by-ticket indexing is implemented three times across two files.
generate_report.pydefines an unusedscan_by_ticket(duplicating its own inline loop at lines 76-78), andgenerate_html_report.pyreimplements the same logic yet again asbuild_scan_index, even though it already imports helpers fromgenerate_report.py.
plugins/edge-cve/scripts/generate_report.py#L29-L35: delete the deadscan_by_ticket, or promote it to the single shared implementation and havemain()call it instead of the inline loop at lines 76-78.plugins/edge-cve/scripts/generate_html_report.py#L87-L92: import and reuse that shared implementation instead ofbuild_scan_index.🤖 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 `@plugins/edge-cve/scripts/generate_report.py` around lines 29 - 35, The scan-by-ticket indexing logic is duplicated across both report generators. In plugins/edge-cve/scripts/generate_report.py lines 29-35, retain scan_by_ticket as the shared implementation and update main() to call it instead of its inline loop; in plugins/edge-cve/scripts/generate_html_report.py lines 87-92, import and reuse scan_by_ticket and remove or replace build_scan_index.plugins/edge-cve/scripts/run_single_repo_scan.sh (1)
1-1: 📐 Maintainability & Code Quality | 🔵 TrivialShebang doesn't match required
#!/usr/bin/bash.See consolidated comment.
🤖 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 `@plugins/edge-cve/scripts/run_single_repo_scan.sh` at line 1, Update the shebang at the start of run_single_repo_scan.sh from #!/usr/bin/env bash to the required #!/usr/bin/bash.Sources: Coding guidelines, Path instructions
plugins/edge-cve/scripts/run_govulncheck_jobs.sh (2)
1-1: 📐 Maintainability & Code Quality | 🔵 TrivialShebang doesn't match required
#!/usr/bin/bash.Same issue as scan_target.sh; see consolidated comment.
🤖 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 `@plugins/edge-cve/scripts/run_govulncheck_jobs.sh` at line 1, Update the shebang at the top of run_govulncheck_jobs.sh to use the required /usr/bin/bash interpreter path, matching scan_target.sh.Sources: Coding guidelines, Path instructions
94-115: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winPython heredoc for parsing
scan-targets.jsonis duplicated inrun_govulncheck_podman.sh.Lines 96-113 are byte-for-byte identical to
run_govulncheck_podman.shlines 137-154. Worth extracting to a small shared helper script (e.g.list_scan_targets.py) invoked by both, so future schema changes toscan-targets.jsononly need updating in one place. See consolidated comment.🤖 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 `@plugins/edge-cve/scripts/run_govulncheck_jobs.sh` around lines 94 - 115, Extract the duplicated scan-target parsing heredoc from run_govulncheck_jobs.sh and run_govulncheck_podman.sh into a shared list_scan_targets.py helper. Preserve the existing target filtering, stderr summary, and pipe-delimited output consumed by both scripts, then invoke the helper with the same arguments and remove both inline Python blocks.plugins/edge-cve/scripts/run_govulncheck_podman.sh (2)
1-1: 📐 Maintainability & Code Quality | 🔵 TrivialShebang doesn't match required
#!/usr/bin/bash.See consolidated comment.
🤖 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 `@plugins/edge-cve/scripts/run_govulncheck_podman.sh` at line 1, Update the shebang at the top of run_govulncheck_podman.sh from #!/usr/bin/env bash to the required #!/usr/bin/bash.Sources: Coding guidelines, Path instructions
130-156: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicated with
run_govulncheck_jobs.sh's target-parsing heredoc.See consolidated comment (shared with
run_govulncheck_jobs.shlines 94-115).🤖 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 `@plugins/edge-cve/scripts/run_govulncheck_podman.sh` around lines 130 - 156, Remove the duplicated target-parsing heredoc from the script’s PYTHON_ARGS/TARGET_LINES flow and reuse the shared parsing implementation established for run_govulncheck_jobs.sh. Preserve repository filtering and the existing target fields/output format while consolidating the logic in one reusable location.plugins/edge-cve/scripts/collect_govulncheck_results.py (2)
42-84: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRuff RUF005: prefer iterable unpacking over list concatenation.
As per coding guidelines,
`**/*.py`: Python code must pass ruff validation. Line 46-54'soc_base(namespace) + [...]triggers RUF005.♻️ Proposed fix
proc = run( - oc_base(namespace) - + [ - "get", - "jobs", - "-l", - "app.kubernetes.io/name=edge-cve-govulncheck", - "-o", - "json", - ], + [*oc_base(namespace), "get", "jobs", "-l", + "app.kubernetes.io/name=edge-cve-govulncheck", "-o", "json"], check=False, )🤖 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 `@plugins/edge-cve/scripts/collect_govulncheck_results.py` around lines 42 - 84, Update the command construction in wait_for_jobs to use iterable unpacking when combining oc_base(namespace) with the additional get jobs arguments, removing the list concatenation that triggers Ruff RUF005. Preserve the existing command order and behavior.Sources: Coding guidelines, Linters/SAST tools
87-116: 🗄️ Data Integrity & Integration | 🔵 TrivialNo scoping to the current run's expected targets — historically-published ConfigMaps accumulate and get re-collected on every future run.
collect_result_configmapsselects onRESULT_LABEL(plus an optional repo filter), but there's nothing here (or inrun_govulncheck_jobs.sh) that deletes/expires ConfigMaps for targets that no longer appear in a newerscan-targets.json(e.g., a resolved ticket dropped from the list). Those stale ConfigMaps keep matching the selector indefinitely and get folded into every subsequent report as if they were fresh, until someone manually cleans the namespace. Also flags the same RUF005 pattern at line 97 as the block above.🤖 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 `@plugins/edge-cve/scripts/collect_govulncheck_results.py` around lines 87 - 116, Update collect_result_configmaps and the run_govulncheck_jobs.sh flow to scope result ConfigMaps to the current scan-targets.json targets, removing or expiring ConfigMaps for targets no longer present so stale results are not re-collected. Preserve repo filtering while adding the run-target boundary, and replace the RUF005-prone list concatenation around the oc command with the project’s preferred iterable-unpacking approach.plugins/edge-cve/scripts/scan_target.sh (1)
1-1: 📐 Maintainability & Code Quality | 🔵 TrivialShebang doesn't match required
#!/usr/bin/bash.As per coding guidelines,
`**/*.sh`: Shebang must be `#!/usr/bin/bash`, and CONTRIBUTING.md reiterates "keep Shell scripts using#!/usr/bin/bash". This file (and the other three shell scripts in this cohort) use#!/usr/bin/env bash. See consolidated comment.🤖 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 `@plugins/edge-cve/scripts/scan_target.sh` at line 1, Update the shebang at the top of scan_target.sh from “#!/usr/bin/env bash” to the required “#!/usr/bin/bash”, preserving the rest of the script unchanged.Sources: Coding guidelines, Path instructions
plugins/edge-cve/scripts/process_govulncheck_result.go (1)
201-233: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winSet an explicit TLS
MinVersionon the in-cluster API client.
tls.Config{RootCAs: pool}relies on Go's implicit default (currently TLS 1.2 for clients). Since this client sends a bearer token to the Kubernetes API, explicitly pinning a floor removes ambiguity about the negotiated floor and guards against any future change in Go's default.🔒 Proposed fix
client := &http.Client{ Transport: &http.Transport{ - TLSClientConfig: &tls.Config{RootCAs: pool}, + TLSClientConfig: &tls.Config{RootCAs: pool, MinVersion: tls.VersionTLS12}, }, }🤖 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 `@plugins/edge-cve/scripts/process_govulncheck_result.go` around lines 201 - 233, Update the TLS configuration created in inClusterClient to explicitly set MinVersion to TLS 1.2 alongside RootCAs, ensuring the Kubernetes API client never negotiates an older protocol.Source: Linters/SAST tools
🤖 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 `@plugins/edge-cve/k8s/govulncheck-job.yaml.template`:
- Around line 18-67: Add pod/container securityContext hardening to the
govulncheck container: run as non-root, disable privilege escalation, use a
read-only root filesystem, and drop all capabilities. Because HOME, GOPATH,
GOCACHE, and GOMODCACHE in the container command flow write under /tmp, add a
writable emptyDir volume mounted at /tmp while preserving the existing workspace
and scripts mounts.
In `@plugins/edge-cve/README.md`:
- Around line 203-210: Make Podman cleanup explicitly confirmed and opt-in: in
plugins/edge-cve/README.md lines 203-210, remove the default system prune
behavior or require explicit confirmation before running it; in
plugins/edge-cve/skills/investigate/SKILL.md lines 161-168, warn users before
local scans and pass --no-prune unless cleanup has been explicitly approved.
In `@plugins/edge-cve/scripts/analyze_scan_result.py`:
- Around line 31-41: Update determine_verdict so every abnormal scan_exit_code
not in (0, 3) returns "inconclusive", regardless of finding_count, while
preserving the existing scan_incomplete and affected handling. Add positive and
negative tests covering scan_exit_code=1 with zero findings and normal clean
results.
In `@plugins/edge-cve/scripts/collect_govulncheck_results.py`:
- Around line 35-39: Update sanitize_label to lowercase the sanitized label,
matching the Go-side sanitizeLabel behavior used for the edge-cve/repo label.
Apply lowercasing consistently before enforcing the 63-character limit.
In `@plugins/edge-cve/scripts/cve-investigator.sh`:
- Around line 105-107: Update the workdir creation branch in check-repo to use a
GNU-compatible mktemp template with trailing Xs, and register cleanup of the
newly created temporary workdir via a trap. Only add the trap when the branch
creates the directory; preserve caller-provided workdir behavior and the
existing results_dir setup.
In `@plugins/edge-cve/scripts/lib/jira_client.py`:
- Around line 76-101: Update search_jql()’s pagination loop to enforce a hard
maximum iteration count and raise an error when nextPageToken repeats or
otherwise fails to advance. Handle missing pagination metadata without silently
truncating results, while preserving normal termination when Jira explicitly
indicates the final page.
In `@plugins/edge-cve/scripts/process_govulncheck_result.go`:
- Around line 243-260: Update sanitizeLabel to match the Python sanitize_label
behavior by removing the uppercase-to-lowercase conversion and preserving
uppercase characters as allowed label content. Truncate the sanitized string to
63 characters before trimming “-”, “_”, and “.” so the final result always ends
with an alphanumeric character and remains consistent with --repo filtering.
- Around line 311-361: Update findingOSV and the matching flow to handle
govulncheck entries where finding.osv is a string ID rather than an embedded
object. Resolve that ID against the available top-level OSV data, preserve the
original finding entry in matched, and retain support for existing
embedded-object and alias matching behavior.
In `@plugins/edge-cve/scripts/run_govulncheck_podman.sh`:
- Around line 241-268: Apply repo_filters when collecting result files in the
aggregation heredoc: inspect each loaded result’s target repo_slug and include
only results matching the requested filters, while retaining all results when no
filters are provided. Update the loop around results_dir.glob and preserve the
existing invalid-JSON warning, payload metadata, counts, and output behavior.
In `@plugins/edge-cve/scripts/scan_target.sh`:
- Around line 42-49: Update the checkout flow in scan_target.sh to fail
immediately when neither the requested GIT_REF nor origin/GIT_REF can be checked
out. Remove the unconditional success fallback after the checkout attempts,
while preserving the existing clone and fetch behavior.
In `@plugins/edge-cve/skills/investigate/SKILL.md`:
- Around line 159-176: Validate the --local and --dry-run combination before the
Step 2 branching logic in the investigation workflow. If both flags are
supplied, stop immediately with a clear incompatibility error; otherwise
preserve the existing local and dry-run behaviors unchanged.
- Around line 47-50: Update the workdir contract used by the investigate
workflow and its documentation: make the default workdir unique per run instead
of reusing a daily path, and validate overridden workdirs by rejecting unsafe or
non-empty directories before execution. In
plugins/edge-cve/skills/investigate/SKILL.md at lines 47-50, document the
generated per-run workdir and override validation; in plugins/edge-cve/README.md
at line 21, update the copy/paste example to use the same contract.
- Around line 178-185: Update the OpenShift investigation workflow around the
cve-investigator.sh scan and collect commands to define explicit stop conditions
for command failures, zero discovered targets, missing result files, malformed
JSON, and partial results. Keep these policies inline beside the affected
invocations, and prevent analysis or finalization from treating stale or
incomplete data as complete; retain the existing timeout guidance while
documenting how each condition is handled.
- Around line 200-219: Update the govulncheck analysis prompt and input flow
around the generalPurpose subagent so private tickets are excluded or redacted
before processing. Ensure cves-parsed.json is never passed directly when it
contains is_private tickets, while preserving the existing analysis of
non-private ticket context and required output file.
- Around line 129-153: Add a validation step between the foreground Agent
instruction and the build_scan_targets.py invocation in the investigation
workflow. Require cves-grouped-reviewed.json to exist and validate against the
cves-grouped.json schema; stop without rebuilding targets if it is missing or
invalid, preventing stale data from being used.
---
Outside diff comments:
In `@plugins/edge-cve/k8s/namespace.yaml`:
- Around line 1-7: Add a Kubernetes NetworkPolicy for the edge-cve-scans
Namespace, using the namespace name and an empty podSelector to cover all pods.
Configure default-deny ingress and egress policy types, while preserving only
the explicitly required egress destinations for scan Jobs if those requirements
are defined in the manifests.
In `@plugins/edge-cve/scripts/test_cve_extract.py`:
- Around line 1-112: Add is_private_ticket to the imported CVE extraction
helpers and extend CveExtractTests with positive coverage for a Private
security_level and Private-CVE label, plus negative coverage for a non-private
ticket. Keep the assertions focused on the boolean result for each case.
---
Minor comments:
In `@plugins/edge-cve/config/component-repos.json`:
- Around line 44-47: The repo_url_patterns entries currently allow trailing
prose punctuation into the captured repo name. Update the repository URL
extraction flow, including extract_repo_urls(), so captured slugs exclude
closing ), ], commas, and periods before the slug is constructed, while
preserving valid repository characters and existing URL matching behavior.
In `@plugins/edge-cve/k8s/rbac.yaml`:
- Around line 12-15: Update the ConfigMap rule under resources ["configmaps"] to
remove the unnecessary "get", "list", and "update" verbs, retaining only
"create" and "patch" for the job’s required operations.
In `@plugins/edge-cve/README.md`:
- Around line 49-51: Update the saved-filter reference in the README to use
descriptive Markdown link syntax instead of a bare URL, preserving the existing
destination and ensuring it complies with repository markdownlint rules.
- Line 15: Update the JIRA_API_TOKEN example in the README to use a quoted
placeholder value, ensuring the export command is valid shell syntax and does
not interpret the placeholder as redirection.
- Around line 107-111: Update the Python dependencies section in the README to
install via the requirements file using python3 -m pip install -r
plugins/edge-cve/requirements.txt, and change the requests dependency in
plugins/edge-cve/requirements.txt from the minimum version constraint to an
exact version pin.
In `@plugins/edge-cve/scripts/build_scan_targets.py`:
- Around line 21-27: Update target_id to append a short deterministic content
hash derived from the original repo_slug and git_ref, while retaining the
existing slugified components for readability. Ensure the hash input
distinguishes the two values unambiguously and is included in every returned ID
so truncation or normalization cannot cause collisions in targets_map or
downstream job addressing.
In `@plugins/edge-cve/scripts/cve-investigator.sh`:
- Around line 9-11: Update the cve-investigator.sh usage header and usage()
output for cmd_check_repo to document both supported options, --repo-slug and
--no-prune, alongside the existing repository arguments. Keep the descriptions
consistent with their parsed behavior and ensure both help locations expose
them.
- Line 1: Update the shebang at the start of the cve-investigator.sh script from
the env-based form to the required direct Bash path, using exactly
#!/usr/bin/bash.
In `@plugins/edge-cve/scripts/run_single_repo_scan.sh`:
- Around line 82-84: Update the REPO_SLUG fallback normalization to support SSH
remotes such as git@github.com:owner/repo.git, preserving the owner/repository
path while removing the SSH host prefix and optional .git suffix. Keep the
existing HTTPS URL handling intact and apply the change within the REPO_SLUG
assignment block.
---
Nitpick comments:
In `@plugins/edge-cve/k8s/govulncheck-job.yaml.template`:
- Line 24: Update the image reference in the govulncheck job template from the
mutable registry.redhat.io/ubi9/go-toolset:1.23 tag to the corresponding
immutable digest-pinned reference, preserving the intended Go toolset version.
In `@plugins/edge-cve/requirements.txt`:
- Line 1: Update the requests dependency declaration in requirements.txt from a
minimum-version constraint to an exact, vetted version pin, following the
repository’s supply-chain guidance; preserve the existing dependency name and
verify or add its hash if supported by the project’s requirements format.
In `@plugins/edge-cve/scripts/collect_govulncheck_results.py`:
- Around line 42-84: Update the command construction in wait_for_jobs to use
iterable unpacking when combining oc_base(namespace) with the additional get
jobs arguments, removing the list concatenation that triggers Ruff RUF005.
Preserve the existing command order and behavior.
- Around line 87-116: Update collect_result_configmaps and the
run_govulncheck_jobs.sh flow to scope result ConfigMaps to the current
scan-targets.json targets, removing or expiring ConfigMaps for targets no longer
present so stale results are not re-collected. Preserve repo filtering while
adding the run-target boundary, and replace the RUF005-prone list concatenation
around the oc command with the project’s preferred iterable-unpacking approach.
In `@plugins/edge-cve/scripts/generate_report.py`:
- Around line 29-35: The scan-by-ticket indexing logic is duplicated across both
report generators. In plugins/edge-cve/scripts/generate_report.py lines 29-35,
retain scan_by_ticket as the shared implementation and update main() to call it
instead of its inline loop; in plugins/edge-cve/scripts/generate_html_report.py
lines 87-92, import and reuse scan_by_ticket and remove or replace
build_scan_index.
In `@plugins/edge-cve/scripts/process_govulncheck_result.go`:
- Around line 201-233: Update the TLS configuration created in inClusterClient
to explicitly set MinVersion to TLS 1.2 alongside RootCAs, ensuring the
Kubernetes API client never negotiates an older protocol.
In `@plugins/edge-cve/scripts/run_govulncheck_jobs.sh`:
- Line 1: Update the shebang at the top of run_govulncheck_jobs.sh to use the
required /usr/bin/bash interpreter path, matching scan_target.sh.
- Around line 94-115: Extract the duplicated scan-target parsing heredoc from
run_govulncheck_jobs.sh and run_govulncheck_podman.sh into a shared
list_scan_targets.py helper. Preserve the existing target filtering, stderr
summary, and pipe-delimited output consumed by both scripts, then invoke the
helper with the same arguments and remove both inline Python blocks.
In `@plugins/edge-cve/scripts/run_govulncheck_podman.sh`:
- Line 1: Update the shebang at the top of run_govulncheck_podman.sh from
#!/usr/bin/env bash to the required #!/usr/bin/bash.
- Around line 130-156: Remove the duplicated target-parsing heredoc from the
script’s PYTHON_ARGS/TARGET_LINES flow and reuse the shared parsing
implementation established for run_govulncheck_jobs.sh. Preserve repository
filtering and the existing target fields/output format while consolidating the
logic in one reusable location.
In `@plugins/edge-cve/scripts/run_single_repo_scan.sh`:
- Line 1: Update the shebang at the start of run_single_repo_scan.sh from
#!/usr/bin/env bash to the required #!/usr/bin/bash.
In `@plugins/edge-cve/scripts/scan_target.sh`:
- Line 1: Update the shebang at the top of scan_target.sh from “#!/usr/bin/env
bash” to the required “#!/usr/bin/bash”, preserving the rest of the script
unchanged.
🪄 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: Repository YAML (base), Central YAML (inherited)
Review profile: CHILL
Plan: Enterprise
Run ID: 4ba48fec-94ec-4892-a78c-bdc990c00aed
📒 Files selected for processing (28)
.claude-plugin/marketplace.json.gitignoreplugins/edge-cve/.claude-plugin/plugin.jsonplugins/edge-cve/README.mdplugins/edge-cve/config/component-repos.jsonplugins/edge-cve/k8s/govulncheck-job.yaml.templateplugins/edge-cve/k8s/namespace.yamlplugins/edge-cve/k8s/rbac.yamlplugins/edge-cve/requirements.txtplugins/edge-cve/scripts/analyze_scan_result.pyplugins/edge-cve/scripts/build_scan_targets.pyplugins/edge-cve/scripts/collect_govulncheck_results.pyplugins/edge-cve/scripts/cve-investigator.shplugins/edge-cve/scripts/fetch_cves.pyplugins/edge-cve/scripts/generate_html_report.pyplugins/edge-cve/scripts/generate_report.pyplugins/edge-cve/scripts/group_cves.pyplugins/edge-cve/scripts/lib/__init__.pyplugins/edge-cve/scripts/lib/cve_extract.pyplugins/edge-cve/scripts/lib/jira_client.pyplugins/edge-cve/scripts/parse_cves.pyplugins/edge-cve/scripts/process_govulncheck_result.goplugins/edge-cve/scripts/run_govulncheck_jobs.shplugins/edge-cve/scripts/run_govulncheck_podman.shplugins/edge-cve/scripts/run_single_repo_scan.shplugins/edge-cve/scripts/scan_target.shplugins/edge-cve/scripts/test_cve_extract.pyplugins/edge-cve/skills/investigate/SKILL.md
Initial edge-cve plugin that fetches open Black CVE Jira tickets, maps them to configured edge components/versions, runs govulncheck via OpenShift Jobs, podman, or ad-hoc single-repo checks, and produces markdown/HTML reports plus remediation prompts. Scans use ticket release refs only (not tip-of-tree main), private tickets are redacted in HTML, and OCP versions are taken from Jira fields/summary so upstream library semver in descriptions is not mistaken for OpenShift releases. Co-Authored-By: Cursor Grok 4.5 <noreply@cursor.com> Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: ehila <ehila@redhat.com>
… workflow Harden job/podman paths, Jira pagination, OSV resolution, workdir/validation gates, and private-ticket redaction before LLM analysis. Co-authored-by: Cursor Grok 4.5 <cursoragent@cursor.com> Signed-off-by: ehila <ehila@redhat.com>
be89556 to
d84bbf8
Compare
There was a problem hiding this comment.
Actionable comments posted: 17
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
🟡 Minor comments (5)
plugins/edge-cve/scripts/test_redact_parsed_for_analysis.py-44-49 (1)
44-49: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winAdd a
timeoutto thesubprocess.runcall.If the script under test deadlocks or hangs, the test will block indefinitely. Adding
timeout=10ensures the test fails fast.🛡️ Proposed fix
result = subprocess.run( [sys.executable, str(SCRIPT), "--workdir", str(workdir)], capture_output=True, text=True, + timeout=10, check=False, )🤖 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 `@plugins/edge-cve/scripts/test_redact_parsed_for_analysis.py` around lines 44 - 49, Update the subprocess.run call in the test to include a 10-second timeout, ensuring hung or deadlocked script execution fails promptly while preserving the existing arguments and result handling.plugins/edge-cve/scripts/test_jira_client.py-12-17 (1)
12-17: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winAvoid shadowing an installed
requestsmodule.
sys.modulesonly reflects imports already performed; in a fresh test process this replaces a realrequestsinstall for the rest of the interpreter. Importrequestsand fall back to the stub only onModuleNotFoundError.🤖 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 `@plugins/edge-cve/scripts/test_jira_client.py` around lines 12 - 17, Update the test setup before importing jira_client to first import the real requests module and only create/register the stub module when that import raises ModuleNotFoundError; do not use the current sys.modules presence check, so an installed requests package is preserved.plugins/edge-cve/scripts/process_govulncheck_result.go-285-290 (1)
285-290: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winSort CVE IDs before serializing them.
Go map iteration is nondeterministic, so identical scans can emit different
cve_idsordering. Sortoutbefore returning to preserve the PR's deterministic-output contract.🤖 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 `@plugins/edge-cve/scripts/process_govulncheck_result.go` around lines 285 - 290, Update mapKeys to sort the collected out slice before returning it, ensuring CVE IDs derived from the map have deterministic ordering while preserving the existing collection behavior.plugins/edge-cve/scripts/run_govulncheck_podman.sh-32-32 (1)
32-32: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winSynchronize Podman memory defaults and remediation guidance. The executable default is
16g, while documentation and the OOM message still reference6g.
plugins/edge-cve/scripts/run_govulncheck_podman.sh#L32-L32: establish the intended default as the source of truth.plugins/edge-cve/README.md#L197-L201: document that same default.plugins/edge-cve/scripts/run_govulncheck_podman.sh#L280-L282: recommend retrying above the current default, not at6g.🤖 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 `@plugins/edge-cve/scripts/run_govulncheck_podman.sh` at line 32, Use CONTAINER_MEMORY in plugins/edge-cve/scripts/run_govulncheck_podman.sh as the source of truth with the 16g default; update plugins/edge-cve/README.md lines 197-201 to document 16g, and update the OOM guidance in plugins/edge-cve/scripts/run_govulncheck_podman.sh lines 280-282 to recommend retrying with memory greater than 16g.plugins/edge-cve/scripts/fetch_cves.py-68-69 (1)
68-69: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winCreate parent directories for every custom output path.
Optional output arguments currently fail with
FileNotFoundErrorwhen their parent directory does not already exist.
plugins/edge-cve/scripts/fetch_cves.py#L68-L69: calloutput_path.parent.mkdir(parents=True, exist_ok=True)before writing.plugins/edge-cve/scripts/group_cves.py#L148-L149: callllm_path.parent.mkdir(parents=True, exist_ok=True)before writing.🤖 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 `@plugins/edge-cve/scripts/fetch_cves.py` around lines 68 - 69, Ensure custom output paths have existing parent directories before writing: in plugins/edge-cve/scripts/fetch_cves.py lines 68-69, create output_path.parent with parents=True and exist_ok=True before the open call; apply the same change to llm_path.parent in plugins/edge-cve/scripts/group_cves.py lines 148-149.
🧹 Nitpick comments (1)
plugins/edge-cve/scripts/scan_target.sh (1)
55-56: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winPin
govulncheckto a fixed version.@latestmakes the scan job non-reproducible and can break when upstream changes; use a centrally declared, tested version instead.🤖 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 `@plugins/edge-cve/scripts/scan_target.sh` around lines 55 - 56, Replace the `@latest` specifier in the govulncheck installation command with the centrally declared, tested fixed version, reusing the repository’s existing version symbol or configuration rather than introducing a new inline version.
🤖 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 `@plugins/edge-cve/scripts/analyze_scan_result.py`:
- Around line 45-53: Update finding_label to handle inner.osv values that are
string IDs as well as mapping-like embedded OSV objects, deriving vuln_id
without calling .get on a string and preserving the existing fallback behavior
for missing data. Add positive and negative tests covering string-valued IDs and
embedded OSV objects, including the expected label output.
In `@plugins/edge-cve/scripts/build_scan_targets.py`:
- Around line 21-26: Make target IDs collision-resistant in target_id within
plugins/edge-cve/scripts/build_scan_targets.py: append a stable digest derived
from the full repo_slug and git_ref after normalization, while preserving the
existing readable slug components. Apply the corresponding change in
plugins/edge-cve/scripts/run_single_repo_scan.sh lines 109-115 by appending a
stable digest of the full repository URL and ref before selecting the result
directory.
In `@plugins/edge-cve/scripts/collect_govulncheck_results.py`:
- Around line 50-59: Update the command construction in the govulncheck result
collection flow, including the additional occurrence, to use iterable unpacking
rather than list concatenation with oc_base(namespace). Preserve the existing
command argument order and behavior while resolving Ruff RUF005 validation
errors.
- Around line 65-80: Update the completion logic in the job-status aggregation
loop to inspect each job’s terminal conditions, rather than treating active == 0
as complete. Only return complete when every job has a Complete or Failed
condition; otherwise preserve the polling path for newly created or retrying
jobs.
In `@plugins/edge-cve/scripts/generate_html_report.py`:
- Around line 203-205: Update the report statistics around the total/affected
calculations and the component/global summary logic to deduplicate rows by their
ticket key before counting. Ensure tickets appearing under multiple versions
contribute once to total and verdict counts, while preserving the existing badge
and summary behavior.
- Around line 423-425: Update the component-loading flow around
load_known_components so an absent or empty mapping is treated as a fatal
configuration error: print an error to stderr and terminate before rendering
Jira components. Remove the fallback behavior that continues with all
components, preserving the report’s edge-only scope.
- Around line 115-132: Update the version grouping loop in the report-generation
flow so private tickets use the neutral version value “Withheld” instead of
their actual versions. Keep non-private tickets grouped by their existing
versions, while preserving the current redaction fields in the row construction
around is_private and versions.
In `@plugins/edge-cve/scripts/process_govulncheck_result.go`:
- Around line 183-198: The doRequest function must bound the Kubernetes API call
and propagate response-body read errors. Configure the provided HTTP client with
an appropriate timeout before client.Do, and capture the error from io.ReadAll,
returning it with an empty httpResult instead of accepting truncated data; apply
the same handling to the additional request path around the referenced lines.
- Around line 293-312: Update readNDJSON to return ([]map[string]any, error),
propagating os.Open failures, JSON decode failures, and scanner.Err() instead of
silently skipping or returning partial entries. Update every caller of
readNDJSON to handle and propagate the error so failed scans cannot produce
clean or not_affected results; preserve skipping blank lines only.
- Around line 35-40: Update main’s SCAN_EXIT parsing to handle the strconv.Atoi
error instead of discarding it. Reject missing or malformed values with a
non-zero process exit and an appropriate error message, while preserving the
parsed scan exit code for valid input. Ensure no error return is ignored.
In `@plugins/edge-cve/scripts/run_govulncheck_podman.sh`:
- Line 1: Update the shebang at the first line of
plugins/edge-cve/scripts/run_govulncheck_podman.sh (line 1) and
plugins/edge-cve/scripts/run_single_repo_scan.sh (line 1) to use the required
/usr/bin/bash interpreter.
- Around line 104-109: Require a timeout utility in both timeout-selection
blocks: plugins/edge-cve/scripts/run_govulncheck_podman.sh lines 104-109 and
plugins/edge-cve/scripts/run_single_repo_scan.sh lines 95-100 must fail with a
clear prerequisite error when neither timeout nor gtimeout is available, rather
than continuing without a wall-clock limit; preserve the existing preference for
timeout, then gtimeout.
- Around line 111-122: Update cleanup_current_container in
plugins/edge-cve/scripts/run_govulncheck_podman.sh (lines 111-122) and the
corresponding signal handling in
plugins/edge-cve/scripts/run_single_repo_scan.sh (lines 130-136) to use separate
INT and TERM handlers that invoke cleanup_current_container and then exit,
preventing execution from resuming after signal cleanup.
In `@plugins/edge-cve/scripts/scan_target.sh`:
- Line 1: Update the shebang at the beginning of scan_target.sh from
#!/usr/bin/env bash to the required exact form, #!/usr/bin/bash.
In `@plugins/edge-cve/scripts/test_redact_parsed_for_analysis.py`:
- Around line 16-58: Add negative test methods to RedactParsedForAnalysisTest
covering a non-list tickets value that exits with code 1, a missing tickets key
that is handled gracefully, non-dict ticket entries being excluded, and an empty
tickets list producing private_redacted_count of 0. Reuse the existing
subprocess/workdir setup and assert the resulting output or exit behavior for
each case.
In `@plugins/edge-cve/scripts/test_validate_grouped_cves.py`:
- Around line 16-17: Replace the hard-coded /tmp path in the grouped CVE fixture
metadata with the relative placeholder cves-parsed.json, preserving the field’s
role as fixture metadata and leaving the surrounding grouped_at data unchanged.
- Around line 41-45: Add a narrowly scoped Ruff suppression comment for S603 to
the subprocess.run call in the test command helper, documenting that the command
uses the interpreter, fixed SCRIPT path, and test-controlled arguments. Keep the
existing subprocess behavior unchanged.
---
Minor comments:
In `@plugins/edge-cve/scripts/fetch_cves.py`:
- Around line 68-69: Ensure custom output paths have existing parent directories
before writing: in plugins/edge-cve/scripts/fetch_cves.py lines 68-69, create
output_path.parent with parents=True and exist_ok=True before the open call;
apply the same change to llm_path.parent in
plugins/edge-cve/scripts/group_cves.py lines 148-149.
In `@plugins/edge-cve/scripts/process_govulncheck_result.go`:
- Around line 285-290: Update mapKeys to sort the collected out slice before
returning it, ensuring CVE IDs derived from the map have deterministic ordering
while preserving the existing collection behavior.
In `@plugins/edge-cve/scripts/run_govulncheck_podman.sh`:
- Line 32: Use CONTAINER_MEMORY in
plugins/edge-cve/scripts/run_govulncheck_podman.sh as the source of truth with
the 16g default; update plugins/edge-cve/README.md lines 197-201 to document
16g, and update the OOM guidance in
plugins/edge-cve/scripts/run_govulncheck_podman.sh lines 280-282 to recommend
retrying with memory greater than 16g.
In `@plugins/edge-cve/scripts/test_jira_client.py`:
- Around line 12-17: Update the test setup before importing jira_client to first
import the real requests module and only create/register the stub module when
that import raises ModuleNotFoundError; do not use the current sys.modules
presence check, so an installed requests package is preserved.
In `@plugins/edge-cve/scripts/test_redact_parsed_for_analysis.py`:
- Around line 44-49: Update the subprocess.run call in the test to include a
10-second timeout, ensuring hung or deadlocked script execution fails promptly
while preserving the existing arguments and result handling.
---
Nitpick comments:
In `@plugins/edge-cve/scripts/scan_target.sh`:
- Around line 55-56: Replace the `@latest` specifier in the govulncheck
installation command with the centrally declared, tested fixed version, reusing
the repository’s existing version symbol or configuration rather than
introducing a new inline version.
🪄 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: Repository YAML (base), Central YAML (inherited)
Review profile: CHILL
Plan: Enterprise
Run ID: 87686335-e842-4c63-93a8-9cee0df74058
📒 Files selected for processing (35)
.claude-plugin/marketplace.json.gitignoreplugins/edge-cve/.claude-plugin/plugin.jsonplugins/edge-cve/README.mdplugins/edge-cve/config/component-repos.jsonplugins/edge-cve/k8s/govulncheck-job.yaml.templateplugins/edge-cve/k8s/namespace.yamlplugins/edge-cve/k8s/rbac.yamlplugins/edge-cve/requirements.txtplugins/edge-cve/scripts/analyze_scan_result.pyplugins/edge-cve/scripts/build_scan_targets.pyplugins/edge-cve/scripts/collect_govulncheck_results.pyplugins/edge-cve/scripts/cve-investigator.shplugins/edge-cve/scripts/fetch_cves.pyplugins/edge-cve/scripts/generate_html_report.pyplugins/edge-cve/scripts/generate_report.pyplugins/edge-cve/scripts/group_cves.pyplugins/edge-cve/scripts/lib/__init__.pyplugins/edge-cve/scripts/lib/cve_extract.pyplugins/edge-cve/scripts/lib/jira_client.pyplugins/edge-cve/scripts/parse_cves.pyplugins/edge-cve/scripts/process_govulncheck_result.goplugins/edge-cve/scripts/process_govulncheck_result_test.goplugins/edge-cve/scripts/redact_parsed_for_analysis.pyplugins/edge-cve/scripts/run_govulncheck_jobs.shplugins/edge-cve/scripts/run_govulncheck_podman.shplugins/edge-cve/scripts/run_single_repo_scan.shplugins/edge-cve/scripts/scan_target.shplugins/edge-cve/scripts/test_analyze_scan_result.pyplugins/edge-cve/scripts/test_cve_extract.pyplugins/edge-cve/scripts/test_jira_client.pyplugins/edge-cve/scripts/test_redact_parsed_for_analysis.pyplugins/edge-cve/scripts/test_validate_grouped_cves.pyplugins/edge-cve/scripts/validate_grouped_cves.pyplugins/edge-cve/skills/investigate/SKILL.md
🚧 Files skipped from review as they are similar to previous changes (14)
- plugins/edge-cve/k8s/namespace.yaml
- plugins/edge-cve/config/component-repos.json
- plugins/edge-cve/scripts/lib/init.py
- plugins/edge-cve/.claude-plugin/plugin.json
- plugins/edge-cve/requirements.txt
- plugins/edge-cve/k8s/rbac.yaml
- .claude-plugin/marketplace.json
- plugins/edge-cve/k8s/govulncheck-job.yaml.template
- .gitignore
- plugins/edge-cve/scripts/lib/jira_client.py
- plugins/edge-cve/scripts/test_cve_extract.py
- plugins/edge-cve/scripts/cve-investigator.sh
- plugins/edge-cve/skills/investigate/SKILL.md
- plugins/edge-cve/scripts/run_govulncheck_jobs.sh
Make target IDs collision-resistant, fix OSV string labels, require timeout tools and signal-safe cleanup, fail closed on bad NDJSON/SCAN_EXIT/config, dedupe HTML stats, and withhold private ticket versions; add covering tests. Co-authored-by: Cursor Grok 4.5 <cursoragent@cursor.com> Signed-off-by: ehila <ehila@redhat.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@plugins/edge-cve/scripts/test_generate_html_report.py`:
- Around line 92-103: Suppress Ruff S603 narrowly on the fixed subprocess test
invocation in plugins/edge-cve/scripts/test_generate_html_report.py lines
92-103, adding a # noqa: S603 with a rationale that the command is fixed. Apply
the same targeted suppression to the fixed redaction-script invocation in
plugins/edge-cve/scripts/test_redact_parsed_for_analysis.py lines 21-26; make no
other changes.
🪄 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: Repository YAML (base), Central YAML (inherited)
Review profile: CHILL
Plan: Enterprise
Run ID: 5587de2d-278b-4f09-99f3-441239168646
📒 Files selected for processing (15)
plugins/edge-cve/scripts/analyze_scan_result.pyplugins/edge-cve/scripts/build_scan_targets.pyplugins/edge-cve/scripts/collect_govulncheck_results.pyplugins/edge-cve/scripts/generate_html_report.pyplugins/edge-cve/scripts/process_govulncheck_result.goplugins/edge-cve/scripts/process_govulncheck_result_test.goplugins/edge-cve/scripts/run_govulncheck_podman.shplugins/edge-cve/scripts/run_single_repo_scan.shplugins/edge-cve/scripts/scan_target.shplugins/edge-cve/scripts/test_analyze_scan_result.pyplugins/edge-cve/scripts/test_build_scan_targets.pyplugins/edge-cve/scripts/test_collect_govulncheck_results.pyplugins/edge-cve/scripts/test_generate_html_report.pyplugins/edge-cve/scripts/test_redact_parsed_for_analysis.pyplugins/edge-cve/scripts/test_validate_grouped_cves.py
🚧 Files skipped from review as they are similar to previous changes (6)
- plugins/edge-cve/scripts/scan_target.sh
- plugins/edge-cve/scripts/analyze_scan_result.py
- plugins/edge-cve/scripts/build_scan_targets.py
- plugins/edge-cve/scripts/run_govulncheck_podman.sh
- plugins/edge-cve/scripts/generate_html_report.py
- plugins/edge-cve/scripts/run_single_repo_scan.sh
Mark trap-invoked cleanup in scan_target.sh, and noqa fixed subprocess invocations in HTML/redaction unit tests. Co-authored-by: Cursor Grok 4.5 <cursoragent@cursor.com> Signed-off-by: ehila <ehila@redhat.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
plugins/edge-cve/scripts/test_generate_html_report.py (1)
93-104: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winBound test subprocesses with a timeout.
Both test paths can hang CI indefinitely if the invoked script blocks.
plugins/edge-cve/scripts/test_generate_html_report.py#L93-L104: addtimeout=10tosubprocess.run.plugins/edge-cve/scripts/test_redact_parsed_for_analysis.py#L22-L27: add the same timeout in_run_with_parsed.🤖 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 `@plugins/edge-cve/scripts/test_generate_html_report.py` around lines 93 - 104, Bound both test subprocess invocations with a 10-second timeout: add timeout=10 to subprocess.run in plugins/edge-cve/scripts/test_generate_html_report.py lines 93-104 and to the subprocess invocation inside _run_with_parsed in plugins/edge-cve/scripts/test_redact_parsed_for_analysis.py lines 22-27.
🤖 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.
Outside diff comments:
In `@plugins/edge-cve/scripts/test_generate_html_report.py`:
- Around line 93-104: Bound both test subprocess invocations with a 10-second
timeout: add timeout=10 to subprocess.run in
plugins/edge-cve/scripts/test_generate_html_report.py lines 93-104 and to the
subprocess invocation inside _run_with_parsed in
plugins/edge-cve/scripts/test_redact_parsed_for_analysis.py lines 22-27.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Central YAML (inherited)
Review profile: CHILL
Plan: Enterprise
Run ID: 02a62e49-c44b-4ca0-ba1e-5ba0ac84a11d
📒 Files selected for processing (3)
plugins/edge-cve/scripts/scan_target.shplugins/edge-cve/scripts/test_generate_html_report.pyplugins/edge-cve/scripts/test_redact_parsed_for_analysis.py
🚧 Files skipped from review as they are similar to previous changes (1)
- plugins/edge-cve/scripts/scan_target.sh
Initial edge-cve plugin that fetches open Black CVE Jira tickets, maps them to configured edge components/versions, runs govulncheck via OpenShift Jobs, podman, or ad-hoc single-repo checks, and produces markdown/HTML reports plus remediation prompts. Scans use ticket release refs only (not tip-of-tree main), private tickets are redacted in HTML, and OCP versions are taken from Jira fields/summary so upstream library semver in descriptions is not mistaken for OpenShift releases.
Summary by CodeRabbit
edge-cve) with theedge-cve:investigateworkflow.govulncheckexecution (OpenShift Jobs or local Podman), and result analysis with actionable verdicts.edge-cve.