OPCT-403: rebase release-0.6 + pin versions for v0.6.6#228
Conversation
## Summary
Fix typos, malformed HTML, broken URL handling, and improve visual
presentation in the web UI report.
## Changes
### 1. Metrics Tab Navigation Fix
**Issue**: Metrics tab failed to load due to hardcoded
`/opct-report.html` in URL split logic, but the report is saved as
`index.html`.
**Fix**: Use regex to strip the last path segment instead of hardcoded
filename.
**Before**:
```javascript
let url = window.location.href.split('/opct-report.html')[0] + path
```
**After**:
```javascript
let base = window.location.href.replace(/\/[^/]*$/, '');
window.open(base + path, '_blank').focus();
```
### 2. Typo and HTML Corrections
**File**: `data/templates/report/report.html`
**Typos fixed** (11 total):
- "filted" → "filtered"
- "Github" → "GitHub" (with missing article "the")
- "disablied" → "disabled"
- "camgd" → "camgi"
- "ALl" → "All"
- "BaslineAPI" → "BaselineAPI"
**HTML fixes**:
- Fixed 4 malformed `</>` close tags → `</p>`
- Fixed `</p></b>` nesting → `</b></p>`
- Removed double `<p><p>` tags
### 3. Runtime Delta Computation Fix
**Files**: `data/templates/report/report.html`,
`internal/opct/archive/metalog.go`
**Issue**: When plugins finish out of order or crash, delta time
computation showed invalid values:
- Plugin 80 (openshift-tests-replay): empty time when it never finishes
- Plugin 99 (artifacts-collector): `2562047h47m16s` (math.MaxInt64 ns)
because predecessor never finished
**Fix**: Replace hardcoded switch with predecessor lookup table that
falls back to plugin's own start time when predecessor never finished.
Frontend displays "-" for missing runtime entries.
<img width="1037" height="358" alt="Screenshot From 2026-06-03 10-14-01"
src="https://github.com/user-attachments/assets/5bd4e977-dc2d-445b-939f-d95d49c88eeb"
/>
### 4. Server Bind Address Improvement
**File**: `pkg/cmd/report/report.go`
Changed default server address from `0.0.0.0:9090` to `127.0.0.1:9090`
for security and clarity (local-only access by default).
### 5. Cluster Info Visual Improvements
**Files**: `data/templates/report/report.html`,
`data/templates/report/report.css`
**Before**:
```
|> OpenShift[4.22.0] Kubernetes[1.35] PlatformType[AWS]
|> archive-name.tar.gz
```
<img width="1363" height="280" alt="Screenshot From 2026-06-03 00-56-07"
src="https://github.com/user-attachments/assets/eff1f934-0931-4be3-ad84-8cb63f9e667d"
/>
**After**: Styled colored badge pills with better visual hierarchy
- Blue badges for OpenShift version
- Green badges for Kubernetes version
- Amber badges for platform type
- Gray monospace badges for archive name (secondary row)
<img width="875" height="235" alt="Screenshot From 2026-06-03 00-56-27"
src="https://github.com/user-attachments/assets/805a99c7-b2f5-4148-b36a-dafe402f1fb3"
/>
## Testing
- [x] Metrics tab navigation verified with `index.html` and renamed
files
- [x] All typos corrected (11 fixes)
- [x] HTML validation passed (no malformed tags)
- [x] Runtime delta tested with crashed plugin scenarios
- [x] Server binds to 127.0.0.1:9090 as expected
- [x] Headline badges render correctly with proper colors
- [x] Local report generation tested with real archive
## Files Changed
- `data/templates/report/report.html`: 40 lines changed
- `data/templates/report/report.css`: 32 lines added
- `internal/opct/archive/metalog.go`: 26 lines changed
- `pkg/cmd/report/report.go`: 6 lines changed
**Total**: 4 files, 98 insertions(+), 32 deletions(-)
## Related
- Parent: [OPCT-400](https://redhat.atlassian.net/browse/OPCT-400)
---
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ket retrieval (#219) ## Summary Add automatic leak detection and redaction to `opct retrieve`, and replace the deprecated SPDY protocol with WebSocket for archive retrieval. Fixes: OPCT-423 ## Key Changes ### 1. Leak Detection & Redaction (redact-by-default) Sensitive data in archives is automatically redacted with `<REDACTED_BY_OPCT>`: - 12 curated patterns from [leaktk/patterns](https://github.com/leaktk/patterns) (gitleaks v8.27.0) - Covers: OpenShift tokens, K8s JWTs, AWS/Azure/GCP keys, PEM private keys, generic secrets, GitHub PATs - Keyword pre-filtering and binary detection for performance - `--debug-only-skip-redact` flag for debugging (with prominent warnings) ### 2. WebSocket Retrieve (replaces deprecated SPDY) Sonobuoy uses `remotecommand.NewSPDYExecutor` which is deprecated since Kubernetes 1.31 and causes transient failures (`unexpected EOF`, `non-zero data after tar EOF`). See [vmware-tanzu/sonobuoy#2032](vmware-tanzu/sonobuoy#2032). The old inline-scanning approach **amplified** this SPDY bug: the cleaner decompresses, parses, scans, and recompresses the tar.gz while it streams over the network. Any network jitter during this process corrupts the gzip/tar state, causing the entire retrieve to fail. With a 109 MB archive, the SPDY stream had to stay stable for ~30s of inline processing — making failures almost guaranteed on retries. This PR implements a custom `downloadFromPod()` that: - Uses `remotecommand.NewWebSocketExecutor` as primary protocol - Falls back to `remotecommand.NewSPDYExecutor` via `NewFallbackExecutor` for older clusters - Downloads to a temp file first (two-phase: download, then scan) ### 3. Two-Phase Architecture Previously, scanning happened inline on the network stream — any jitter caused corruption. Now: 1. **Download** — stream pod exec output to temp file on disk (fast, no parsing) 2. **Scan/Redact** — process from disk (reliable I/O), then extract This eliminates the SPDY corruption problem entirely: even if the download uses SPDY fallback, the stream is just raw bytes to disk — no gzip/tar parsing inline. ### Performance Comparison (same cluster, same archive, OCP 4.22.0-ec.5) | Metric | main (SPDY, no scan) | PR (WebSocket + scan + redact) | |--------|---------------------|-------------------------------| | **Success rate** | ~50% (1 retry needed) | **100%** (first attempt) | | **Wall clock** | 34s (incl. 1 retry) | **32s** | | **User CPU** | 9.86s | 11.54s | | **System CPU** | 0.95s | 0.64s | | **Memory (RSS)** | 207 MB | 208 MB | | **Context switches** | 214,521 | 40,013 | | **Files processed** | N/A | 1,190 files | | **Secrets redacted** | 0 | **17 findings** | Key takeaways: - **Same total time** (~32s) despite adding full leak scanning and redaction of 1,190 files - **5x fewer context switches** (40k vs 214k) — WebSocket is more efficient than SPDY - **100% success rate** vs main branch which failed on first attempt with `unexpected EOF` - Main branch needed a retry (SPDY bug) and still took 34s without any scanning ## Changes ### New Files - `internal/cleaner/leakpatterns.go` — 12 curated leak detection patterns - `internal/cleaner/leakscanner.go` — scan and redact implementation - `internal/cleaner/leakscanner_test.go` — 20 unit tests + benchmarks - `docs/devel/enhancements/2026-05-27-retrieve-leak-detection.md` — enhancement doc ### Modified Files - `pkg/retrieve/retrieve.go` — WebSocket+SPDY fallback executor, two-phase retrieve - `internal/cleaner/cleaner.go` — integrated redaction into tar processing pipeline - `internal/cleaner/cleaner_test.go` — updated test expectations for redaction marker - `.github/workflows/e2e.yaml` — E2E test for leak detection and redaction - `.gitignore` — exclude tar.gz archives ## Testing **Unit tests** — all passing: ``` ok github.com/redhat-openshift-ecosystem/opct/internal/cleaner 0.006s ``` **Live cluster test** (OCP 4.22.0-ec.5, K8s v1.35.3, 6 nodes, 109.5 MB archive): ``` INFO Collecting results... INFO Downloading archive from aggregator server... DEBU Discovered aggregator server running on pod opct/sonobuoy... INFO Downloaded 109.5 MB in 19s INFO Scanning archive for sensitive data... DEBU Finished processing 1190 files DEBU Leak scan: 17 potential finding(s) detected and redacted INFO Results saved to opct_202606081827_31f5f586.tar.gz ``` Wall clock: **32s** (vs 34s on main without scanning) ## Test plan - [x] `make build` succeeds - [x] `make test` — all unit tests pass - [x] `make vet` — no issues - [x] Live cluster retrieve completes in ~32s (same as main without scanning) - [x] Redaction markers present in output (17 findings) - [x] Original secrets not present in output - [x] `--debug-only-skip-redact` flag works with warnings - [x] E2E test validates redaction end-to-end - [x] WebSocket protocol with SPDY fallback for older clusters Co-Authored-By: Claude Code <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
**What this PR does / why we need it**: This change introduce the fix to set the correct suite name on OCP 5, where the name changed starting in 4.20. https://redhat.atlassian.net/browse/OPCT-426 **Which issue(s) this PR fixes** *(optional, use `fixes #<issue_number>(, fixes #<issue_number>, ...)` format, where issue_number might be a GitHub issue, or a Jira story*: Fixes # **Checklist** - [x] Subject and description added to both, commit and PR. - [x] Relevant issues have been referenced. - [ ] This change includes docs. - [ ] This change includes unit tests.
## Summary - Add `verify-images` job to `test-build-release` workflow that checks all plugin images referenced in `pkg/types.go` exist on quay.io - Gate the `e2e` job on `verify-images` so the pipeline blocks if any image is missing - Uses the public Quay v2 API (no auth needed) to verify manifests ## Why When bumping versions in `pkg/types.go` for a release, if the `provider-certification-plugins` CI failed to build/push the plugin images, the OPCT binary would ship referencing non-existent images — broken at runtime. This was flagged by CodeRabbit on PR #215 but had no automated gate. ## Images verified Extracted from `pkg/types.go`: - `quay.io/opct/plugin-openshift-tests:TAG` - `quay.io/opct/plugin-artifacts-collector:TAG` - `quay.io/opct/must-gather-monitoring:TAG` ## Test plan - [x] CI runs the new `verify-images` job and passes (current v0.6.5 images exist) - [x] Local verification passes: ``` ✅ quay.io/opct/plugin-openshift-tests:v0.6.5 ✅ quay.io/opct/plugin-artifacts-collector:v0.6.5 ✅ quay.io/opct/must-gather-monitoring:v0.6.5 All plugin images verified successfully. ``` - [ ] Verify failure mode: temporarily change a version to non-existent tag → job should fail 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
**What this PR does / why we need it**: Fix typo in the URL path of assets used by AI Review Assistant. **Which issue(s) this PR fixes** *(optional, use `fixes #<issue_number>(, fixes #<issue_number>, ...)` format, where issue_number might be a GitHub issue, or a Jira story*: Fixes # **Checklist** - [ ] Subject and description added to both, commit and PR. - [ ] Relevant issues have been referenced. - [x] This change includes docs. - [ ] This change includes unit tests.
…canner (#223) ## Summary leaktk-gcs-filter was replacing OPCT CI archives in GCS because PR #219's scanner missed sensitive data. Ran leaktk scan with Red Hat internal patterns against the CI archive from S3: 3157 findings before, 0 after this fix. Fixes: OPCT-428 ## Changes ### 1. Add .tar.xz nested archive support (internal/cleaner/cleaner.go) Must-gather archives use .tar.xz compression. The scanner only recursed into .tar.gz files, so .tar.xz archives (43 MB) were copied without scanning. Added ScanPatchTarXzReaderFor() using the xz library already in go.mod. ### 2. Increase scan size limit (internal/cleaner/leakscanner.go) Changed maxLeakScanSize from 10MB to 100MB. The 60MB HTML/JSON test result files inside nested archives were skipping the scan entirely. ### 3. Add 4 new leak patterns (internal/cleaner/leakpatterns.go) - Generic Secret YAML (rnWF160pWNg): catches token:, secret:, clientSecret: in YAML - Authorization Header (QqS4RvI6Zmg): catches Authorization: Bearer/Basic headers - Broad JWT (RS256): catches OIDC/audience tokens beyond service account JWTs - Unescaped registry auth: catches pull secrets in unescaped JSON format ### 4. Remove files with encoded secrets (internal/cleaner/cleaner.go) - Remove machineconfigs.json (percent+base64 encoded pull secrets, leaktk decodes but OPCT does not) - Remove all packagemanifests.json (base64-encoded PEM keys, previously kept 1 copy) ## Test Results ``` BEFORE: 3157 findings (leaktk + Red Hat patterns) AFTER: 0 findings ``` Tested with leaktk v0.3.3 using Red Hat pattern server (patterns.security.redhat.com) against S3 archive s3://opct-archive/uploads/5.0.0-0.nightly-2026-06-10-003138-20260611-HighlyAvailable-aws-External.tar.gz ## Test plan - [x] go build succeeds - [x] go test ./internal/cleaner/ — all tests pass - [x] opct adm cleaner runs on CI archive, produces cleaned output - [x] leaktk scan on cleaned output: 0 findings - [ ] CI periodic job produces archive not redacted by leaktk-gcs-filter --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - Change plugin image references in `pkg/types.go` to use `latest` tag on `main` branch - Add GHA CI guard in `verify-images` job to block `latest` tags on `release-*` branches - Skip quay.io image verification when using `latest` tags ## Why The 5.0 CI job already tests `opct:latest`. By using `latest` in `types.go` on `main`, merged plugin fixes are immediately testable in CI without waiting for a version bump PR. At release time, a PR to `release-0.6` pins the versions to the specific release tag (e.g., `v0.6.6`). ## Changes ### `pkg/types.go` - `ControllerImage`: `v0.6.5` → `latest` - `PluginsImage`: `v0.6.5` → `latest` - `CollectorImage`: `v0.6.5` → `latest` - `MustGatherMonitoringImage`: `v0.6.5` → `latest` ### `.github/workflows/go.yaml` - New step: "Block latest tags on release branches" — fails CI if `types.go` has `:latest` on `release-*` branches - Updated step: "Extract and verify plugin images" — skips quay.io verification when using `latest` tags ## Impact on release process - **Before:** PR to `main` to bump version → rebase `release-0.6` from main - **After:** Rebase `release-0.6` from main → PR to `release-0.6` to pin version See [OPCT-421 Phase 5](https://redhat.atlassian.net/browse/OPCT-421) for updated release steps. ## Verification - `make test` — all tests pass - `go build ./...` — builds successfully 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.45.0 to 0.55.0. <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/golang/net/commit/7770ec48d03fec35e378665337b4faca93c38423"><code>7770ec4</code></a> go.mod: update golang.org/x dependencies</li> <li><a href="https://github.com/golang/net/commit/4ece7b612ad44ad6c4d5e0d5d4df9c18cc211905"><code>4ece7b6</code></a> html: escape greater-than symbol in doctype identifiers</li> <li><a href="https://github.com/golang/net/commit/08be507abce89191d78cd49da60f4501fc910472"><code>08be507</code></a> html: improve Noah's Ark clause performance</li> <li><a href="https://github.com/golang/net/commit/a8fb2fe4f7378f816302b9f2f7b8290ce512e5dd"><code>a8fb2fe</code></a> html: properly render fostered elements in foreign content</li> <li><a href="https://github.com/golang/net/commit/0dc5b7a5f81d7155ade6d5e9db35992998679932"><code>0dc5b7a</code></a> html: properly check namespace in "in body" any other end tag</li> <li><a href="https://github.com/golang/net/commit/a452f3cc17168a60bc3f439a3ae0fcffc32eca0e"><code>a452f3c</code></a> html: ignore duplicate attributes during tokenization</li> <li><a href="https://github.com/golang/net/commit/f8651996b24ba47d89dd9eb97fd47758e6d1886f"><code>f865199</code></a> quic: fix appendMaxDataFrame erroneously accumulating sentLimit</li> <li><a href="https://github.com/golang/net/commit/210ed3cb901cb549818aefa04b71dadaf149d05d"><code>210ed3c</code></a> quic: establish a "happened-before" relationship between stream write and read</li> <li><a href="https://github.com/golang/net/commit/ad8140e0aa2ec41b37ea478b4525a423bcc21af9"><code>ad8140e</code></a> quic: fix buffer slicing when handling overlapping stream data</li> <li><a href="https://github.com/golang/net/commit/23ee2efe81a3ff183b4eca46c42f749af7efca45"><code>23ee2ef</code></a> http2: avoid API changes when built with go1.27</li> <li>Additional commits viewable in <a href="https://github.com/golang/net/compare/v0.45.0...v0.55.0">compare view</a></li> </ul> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…OCP 4.20+ (#227) ## Summary Update the OPCT documentation to unblock VCSP validations on OCP 4.20+ and address the acceptance criteria from [OPCT-389](https://redhat.atlassian.net/browse/OPCT-389). ### Changes - Added `v0.6.5+` row supporting OCP 4.19-4.22 (CI workflows hardcode `quay.io/opct/opct:v0.6.5`) - Narrowed previous `v0.6.1+` to `v0.6.1-v0.6.4` covering 4.16-4.19 - Removed the OCPBUGS-77783 blocking notice - Added info block documenting: - Affected versions: OPCT v0.6.0 and earlier do not support 4.20+ - Fix is in `openshift-tests` (openshift/origin), not in OPCT or plugins - OCP 4.20 was not affected by the conformance suite bug - OCP 4.21+ needs nightly or z-stream with origin PR #31353 (4.21) / #31270 (4.22) ### Why v0.6.5+ and not v0.6.1+ or v0.6.6+? - All CI nightly workflows hardcode `OPCT_CLI_IMAGE: "quay.io/opct/opct:v0.6.5"` - The conformance fix is in openshift/origin, not OPCT — no OPCT code change was needed - v0.6.6 does not exist yet, and no changes after v0.6.5 are required for 4.20+ support ### CI note The `e2e / e2e-cmd_adm-parse-metrics` test fails on this PR due to a missing test artifact on CloudFront (HTTP 403). This is a pre-existing infrastructure issue unrelated to this docs-only change. Fixes: https://redhat.atlassian.net/browse/OPCT-389 Epic: https://redhat.atlassian.net/browse/OPCT-421 ## Test plan - [ ] Verify version matrix renders correctly on the published docs site - [ ] Verify info block renders correctly - [ ] Confirm no other docs reference the removed blocking notice 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Release: v0.6.1 ## Changes Since v0.6.0 This release includes critical fixes to the auto-release-tag workflow and improvements to the release process. ### Key Changes - Fixed auto-release-tag workflow YAML syntax error (PR #195) - Added security fixes for untrusted input handling in GitHub Actions - Created yamllint configuration for workflow validation - Improved release automation with proper guardrails ### Security Improvements - GitHub Actions expressions now passed through environment variables - Prevents script injection attacks from untrusted PR content ### Release Automation - Auto-release-tag workflow validated and tested - All security guardrails verified and active ## Checklist - [x] Plugin images released at v0.6.1 - [x] CI passing on main - [x] Workflow fixes merged (PR #195) - [x] Auto-release-tag workflow validated - [x] Conflicts resolved in feature branch --- **Note**: This PR will automatically create the v0.6.1 tag when merged, thanks to the auto-release-tag workflow. 🤖 Claude Code Assistant Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
…g builds (#198) ## Problem The `only-new-issues: true` flag in golangci-lint-action fails on tag pushes because there's no base commit to compare against. When building from a tag (like `v0.6.1`), the action tries to compare with commit `0000000000000000000000000000000000000000` which results in a 404 error: ``` failed to fetch push patch: RequestError [HttpError]: Not Found url: '.../compare/0000000000000000000000000000000000000000...COMMIT' ``` This broke the v0.6.1 release build: https://github.com/redhat-openshift-ecosystem/opct/actions/runs/19982041880 ## Solution Remove the `only-new-issues` flag from `.github/workflows/pre_linters.yaml` line 65. This allows golangci-lint to run on the full codebase for all builds (PRs, branches, and tags), which is acceptable since: - The code was already linted when merged to main and release-0.6 - Tag builds should validate the entire codebase anyway - The lint check completes quickly enough (~30 seconds) ## Impact - ✅ Fixes v0.6.1 release build - ✅ Prevents similar failures in future releases -⚠️ May show more lint issues in PR builds (previously only showed new issues) ## Testing After merge: 1. Delete and recreate v0.6.1 tag 2. Verify CI build succeeds --- 🤖 Claude Code Assistant Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
Merge main into release-0.6 to prepare for v0.6.4-rc.1 tag. Includes: - PR #205: fix kube-conformance test extraction for OCP 4.20+ - PR #206: extract cluster pull-secret for release image auth After merge, create tag `v0.6.4-rc.1` from `release-0.6` branch. --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
/lgtm |
Summary
Rebase release-0.6 from main and pin plugin image versions to v0.6.6 for release.
Changes since v0.6.5
Bug Fixes
Enhancements
Dependencies
Version pin
pkg/types.go: pinned all image references fromlatesttov0.6.6Fixes: https://redhat.atlassian.net/browse/OPCT-403
Epic: https://redhat.atlassian.net/browse/OPCT-421
🤖 Generated with Claude Code