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>
|
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 |
|
/approve |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: vr4manta 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 |
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