Skip to content

OCPBUGS-99434: Show toast notification for invalid Helm Chart repositories#16792

Open
martinszuc wants to merge 8 commits into
openshift:mainfrom
martinszuc:HELM-586
Open

OCPBUGS-99434: Show toast notification for invalid Helm Chart repositories#16792
martinszuc wants to merge 8 commits into
openshift:mainfrom
martinszuc:HELM-586

Conversation

@martinszuc

@martinszuc martinszuc commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Analysis / Root cause:

Follow-up to PR #15624 (RFE-7965) which added basicAuth support for ProjectHelmChartRepository. That PR only covered the success case — when a user configures incorrect credentials or a misconfigured Secret (e.g., typo in key name), charts from the affected repository silently disappear from the Developer Catalog with no feedback.

Two gaps existed:

  1. The backend set a console-warning annotation on the aggregated index.yaml response for repos that failed to fetch, but the frontend never read it.
  2. Configuration-level errors (missing Secret keys, missing ConfigMaps, HTTPS required for basicAuth) were silently logged server-side and the repo was dropped before reaching the index fetch stage.

Solution description:

Backend:

  • Improved HTTP error messages in repos.go — 401/403 returns "authentication failed (HTTP %d)" instead of dumping the raw Go response struct. Other non-200 returns "failed to fetch index (HTTP %d)". Added defer resp.Body.Close() to fix a pre-existing resource leak.
  • Updated HelmRepoGetter.List() to return configuration-level errors (missing Secret keys, missing ConfigMaps, HTTPS required) alongside valid repos, instead of silently dropping misconfigured repos.
  • Changed the console-warning annotation from a flat string to a JSON array of {name, error} objects to support frontend i18n.
  • Updated proxy.go to merge both config-level and fetch-level errors into a single annotation.

Frontend:

  • useHelmCharts.tsx now parses the console-warning JSON annotation and displays a danger toast notification via useToast(). The toast appears when the entire Software Catalog is opened (not just the Helm Charts filter), since the index.yaml aggregation runs for all catalog types. Uses a useRef to prevent duplicate toasts on re-renders. Toast is dismissible and auto-dismisses after the default timeout.
  • Added i18n keys for toast title and content.

Tests:

  • Updated TestHelmRepoGetter_ListErrors to assert that misconfigured repos produce the correct configErrors with expected repo names and non-empty error messages.

Screenshots / screen recording:

Auth failure (wrong credentials) — toast on Software Catalog:

scenario1-sw

Auth failure — toast on Helm Charts catalog filter:

scenario1-charts

Unreachable repo — connection timeout error:

unreachable-timeout-1

Config error (typo in Secret key name — usenrame instead of username):

bad-secret

Test setup:

  1. A private HTTPS Helm Chart repository with basic auth is required. Reusable setup scripts are available at openshift-helm/test-scenarios/helm-586-error-notification.
  2. Quick setup:
    # Deploy HTTPS + basicAuth Helm repo on an EC2 instance
    cd test-scenarios/basic-auth-test
    ./run-setup.sh <EC2_IP> full
    
    # Apply good-credentials repo to the cluster
    oc apply -f /tmp/openshift-helm-repo-setup.yaml
    
    # Create a bad-credentials repo for testing
    oc create secret generic helm-bad-auth -n helm-test \
      --from-literal=username=wronguser --from-literal=password=wrongpass
    # Then create a ProjectHelmChartRepository pointing at the bad secret
  3. Full step-by-step instructions with all scenarios are documented in the test-scenarios README.

Test cases:

  • Toast appears with auth failure when repository has wrong credentials (401/403)
  • Toast appears with config error when Secret has wrong key names (e.g., usenrame instead of username)
  • Toast appears with connection error when repository URL is unreachable
  • Toast shows multiple errors when multiple repos are misconfigured
  • Toast does not appear after fixing credentials and reloading
  • Toast does not appear for disabled repositories
  • Toast does not appear in namespaces without misconfigured repos
  • Charts from correctly configured repos still load alongside the error toast
  • Toast is dismissible and auto-dismisses after timeout
  • Toast appears on both Software Catalog (all types) and Helm Charts filter

Browser conformance:

  • Chrome
  • Firefox
  • Safari (or Epiphany on Linux)

Additional info:

Reviewers and assignees:

Summary by CodeRabbit

  • New Features
    • Added toast notifications for Helm chart repository reachability issues, including localized summaries of unreachable repositories.
  • Bug Fixes
    • Improved Helm chart repository indexing resilience: indexing now continues when some repositories have configuration/access problems, and unreachable-repo details are surfaced to users.
    • Enhanced handling of chart index HTTP failures, with clearer authentication-related errors.
  • Localization
    • Added new English translation strings for Helm chart repository error messaging (including unreachable repository lists).

martinszuc and others added 2 commits July 21, 2026 15:59
When a Helm Chart repository has incorrect basicAuth credentials or is
unreachable, the backend already marks it in the index.yaml response
via a console-warning annotation, but the frontend never read it.

Backend: Improve error messages to distinguish auth failures (401/403)
from other errors, and include the error reason in the annotation.

Frontend: Read the console-warning annotation from the index.yaml
response and display it as a toast notification on the catalog page.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Martin Szuc <mszuc@redhat.com>
… support

Surface both fetch-level errors (auth failures, timeouts) and config-level
errors (missing secret keys, missing ConfigMaps, HTTPS required) in the
console-warning annotation. Previously config errors were silently logged
and the repo was dropped without user notification.

Change List() to return config errors alongside valid repos so IndexFile()
can merge them into the annotation. Use AlertVariant.danger (red) for the
toast. Fix newline join to comma-space for proper HTML rendering.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Martin Szuc <mszuc@redhat.com>
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 21, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

@martinszuc: This pull request references HELM-586 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the task to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Analysis / Root cause:

Solution description:

Screenshots / screen recording:

Test setup:

Test cases:

Browser conformance:

  • Chrome
  • Firefox
  • Safari (or Epiphany on Linux)

Additional info:

Reviewers and assignees:

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Helm repository listing now returns structured per-repository errors. The chart proxy serializes these errors into a warning annotation, and the frontend parses the annotation to show a localized danger toast for unreachable repositories.

Changes

Helm repository error reporting

Layer / File(s) Summary
Repository error contract and collection
pkg/helm/chartproxy/repos.go, pkg/helm/chartproxy/repos_test.go
HelmRepoGetter.List returns valid repositories and InvalidRepo entries for configuration failures, with tests covering error names and messages. HTTP handling closes response bodies and distinguishes authentication failures.
Chart proxy warning annotation
pkg/helm/chartproxy/proxy.go, pkg/helm/actions/utility.go
Chart indexing combines repository and index-load failures, JSON-marshals structured errors into the warning annotation, and updates callers for the expanded listing result.
Localized frontend warning toast
frontend/packages/helm-plugin/src/catalog/providers/useHelmCharts.tsx, frontend/packages/helm-plugin/locales/en/helm-plugin.json
The chart provider parses warning annotations and shows each repository warning once using localized danger-toast messages.

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

Suggested reviewers: sowmya-sl

Sequence Diagram(s)

sequenceDiagram
  participant HelmRepoGetter
  participant ChartProxy
  participant useHelmCharts
  participant Toast
  HelmRepoGetter->>ChartProxy: Return repositories and InvalidRepo entries
  ChartProxy->>ChartProxy: JSON-marshal console-warning annotation
  ChartProxy-->>useHelmCharts: Return chart index with console-warning
  useHelmCharts->>Toast: Show localized danger notification
Loading

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
No-Sensitive-Data-In-Logs ❌ Error New klog.Errorf calls log full repo objects/URLs, which can include internal hostnames and basic-auth userinfo; error text also echoes secret names. Log only repo name/namespace and sanitized status codes. Avoid printing unstructured item or helmRepo structs; redact URLs/userinfo and secret identifiers before logging.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (13 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed Touched tests use static table-driven names via tt.name; no It/Describe/Context/When titles or dynamic values (IPs, UUIDs, dates, suffixes) were found.
Test Structure And Quality ✅ Passed Touched tests are plain table-driven unit tests, not Ginkgo specs; no Eventually/Consistently or cluster waits were added, and cleanup scripts run after the TLS helper.
Microshift Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; the only actual diff is a React hook, with no MicroShift-unsupported OpenShift APIs or test assumptions.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The PR only changes a frontend toast hook; no new Ginkgo/e2e tests or multi-node/SNO assumptions were added.
Topology-Aware Scheduling Compatibility ✅ Passed PASS: The PR only updates Helm repo warning handling/toasts and error propagation; no manifests/controllers/scheduling constraints, nodeSelectors, affinity, spread rules, or replica logic were added.
Ote Binary Stdout Contract ✅ Passed Touched files are library/test/frontend only; no main/TestMain/init/suite setup or stdout writes were added.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed PASS: The PR adds only unit/frontend changes; no new Ginkgo e2e specs or external-network-dependent tests were introduced, and the modified test code uses standard testing.
No-Weak-Crypto ✅ Passed Touched files only add TLS/HTTP error handling and toast parsing; no MD5/SHA1/DES/RC4/3DES/Blowfish/ECB, custom crypto, or secret/token compares found.
Container-Privileges ✅ Passed PR diff only changes TSX/Go/JSON files; no container/K8s manifest settings like privileged, hostNetwork, or allowPrivilegeEscalation were found.
Title check ✅ Passed The title clearly matches the PR's main change: warning toasts for invalid Helm Chart repositories.
Description check ✅ Passed The description covers all required sections and explains the root cause, solution, testing, screenshots, and conformance.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@openshift-ci
openshift-ci Bot requested review from sowmya-sl and webbnh July 21, 2026 14:18
@openshift-ci openshift-ci Bot added component/backend Related to backend component/helm Related to helm-plugin approved Indicates a PR has been approved by an approver from all required OWNERS files. kind/i18n Indicates issue or PR relates to internationalization or has content that needs to be translated labels Jul 21, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 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 `@pkg/helm/chartproxy/repos_test.go`:
- Around line 303-313: The config-error test continues indexing configErrors
after reporting a length mismatch, which can panic when it is shorter than
expected. In the test loop around expectedConfigErrorRepo, return or otherwise
stop execution immediately after the len(configErrors) mismatch, while
preserving the existing per-repository assertions for matching lengths.

In `@pkg/helm/chartproxy/repos.go`:
- Around line 276-278: Preserve errors from metadata-name extraction in both
affected paths at pkg/helm/chartproxy/repos.go lines 276-278 and 293-295:
capture the error returned by unstructured.NestedString and incorporate it into
the InvalidRepo error instead of discarding it. Prefer a shared helper for
consistent handling across both sites, while retaining the extracted name when
available.
- Line 90: Update the deferred response-body cleanup in the relevant repository
request function to use a closure that checks the error returned by
resp.Body.Close() and logs any failure through the existing logging mechanism,
rather than discarding it. Preserve the current cleanup behavior and use the
function’s established logger.
🪄 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: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c5faed9f-f128-49c6-9c7a-b593da53f112

📥 Commits

Reviewing files that changed from the base of the PR and between 6d0dcf1 and 4fa0d7b.

📒 Files selected for processing (6)
  • frontend/packages/helm-plugin/locales/en/helm-plugin.json
  • frontend/packages/helm-plugin/src/catalog/providers/useHelmCharts.tsx
  • pkg/helm/actions/utility.go
  • pkg/helm/chartproxy/proxy.go
  • pkg/helm/chartproxy/repos.go
  • pkg/helm/chartproxy/repos_test.go

Comment thread pkg/helm/chartproxy/repos_test.go
Comment thread pkg/helm/chartproxy/repos.go
Comment thread pkg/helm/chartproxy/repos.go Outdated
martinszuc and others added 2 commits July 21, 2026 17:01
Use t.Fatalf for config error count mismatch to prevent index-out-of-bounds
panic in subsequent loop. Log resp.Body.Close() errors instead of silently
discarding them. Add fallback name for repos where metadata.name extraction
fails.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Martin Szuc <mszuc@redhat.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Martin Szuc <mszuc@redhat.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
pkg/helm/chartproxy/repos.go (1)

272-275: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Propagate repository-listing failures.

These branches log dynamic-client errors but return nil, making RBAC/API outages appear as successful empty or partial repository lists. Return the original error; reserve []InvalidRepo for per-repository configuration failures.

As per path instructions, **/*.go requires error returns not to be ignored.

Also applies to: 292-295

🤖 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 `@pkg/helm/chartproxy/repos.go` around lines 272 - 275, Update the
repository-listing error branches in the function containing clusterRepos and
the corresponding branch around the other repository list to return the original
dynamic-client error instead of nil. Preserve logging and existing
helmRepos/configErrors values, while reserving InvalidRepo entries for
per-repository configuration failures.

Source: Path instructions

🤖 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 `@pkg/helm/chartproxy/repos.go`:
- Around line 90-94: Update the response-body close error handling in the
surrounding repository-fetch function to avoid logging indexURL verbatim, since
it may include basic-auth credentials from h.URL.User. Log a redacted URL or
only the safe host and path while preserving the existing close-error message
and behavior.

---

Outside diff comments:
In `@pkg/helm/chartproxy/repos.go`:
- Around line 272-275: Update the repository-listing error branches in the
function containing clusterRepos and the corresponding branch around the other
repository list to return the original dynamic-client error instead of nil.
Preserve logging and existing helmRepos/configErrors values, while reserving
InvalidRepo entries for per-repository configuration failures.
🪄 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: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c30fb227-dab7-437c-830a-09e460494b7b

📥 Commits

Reviewing files that changed from the base of the PR and between 4fa0d7b and 880ecdb.

📒 Files selected for processing (2)
  • pkg/helm/chartproxy/repos.go
  • pkg/helm/chartproxy/repos_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/helm/chartproxy/repos_test.go

Comment thread pkg/helm/chartproxy/repos.go Outdated
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Martin Szuc <mszuc@redhat.com>
@webbnh

webbnh commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

/retest

@webbnh webbnh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This change is OK as it stands, but I think you should probably use a different approach to the i18n for the name: error strings. And, I've flagged several other items for your consideration.

/lgtm

Comment on lines +69 to +71
const repoList = repos
.map((r) => t('{{name}}: {{error}}', { name: r.name, error: r.error }))
.join(', ');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The translation key '{{name}}: {{error}}' seems odd and basically unwieldy. I don't think we can predict the value of name (that's basically user-supplied, right??), and therefore we cannot define a translation for this key before the fact (or, frankly, after the fact!).

Moreover, it's not obvious to me that internationalizing the name is possible or desirable. So, I think that we should be translating only the error, e.g.:

Suggested change
const repoList = repos
.map((r) => t('{{name}}: {{error}}', { name: r.name, error: r.error }))
.join(', ');
const repoList = repos
.map((r) => r.name + ': ' + t(r.error))
.join(', ');

And, of course, to make this work properly, we need to replace the proposed line 25 of frontend/packages/helm-plugin/locales/en/helm-plugin.json with instances of all of our favorite error messages.

"Browse for charts that help manage complex installations and upgrades. Cluster administrators can customize the content made available in the catalog.<1></1>": "Browse for charts that help manage complex installations and upgrades. Cluster administrators can customize the content made available in the catalog.<1></1>",
"README": "README",
"README not available": "README not available",
"{{name}}: {{error}}": "{{name}}: {{error}}",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm not certain, but I think this entry is useless: my understanding is, the translation will apply to everything not inside {{...}}...which is just the colon (which requires no translation).

So, we can omit this from here, omit the t() call which references it, and just fill in the template.

Alternatively, see my comment below.

Comment thread pkg/helm/chartproxy/proxy.go Outdated
Comment on lines +82 to +83
annotations := make(map[string]string)
var invalidRepos []string
invalidRepos := append([]InvalidRepo{}, configErrors...)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are you sure that you want to be making a copy of configErrors, here?

My instinct is that, if we're concerned about mutating the list that List() returned, then that function should have the responsibility of creating the copy (but I could be wrong...).

If we really want/need to make a copy, consider using Clone() instead:

	invalidRepos := slices.Clone(configErrors)

so that the intention is explicit.

Comment on lines +129 to +133
data, err := json.Marshal(invalidRepos)
if err == nil {
annotations[warning] = string(data)
indexFile.Annotations = annotations
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If json.Marshal() returns an error here, we silently ignore it and move on...which is kind of unsatisfying.

If this is a "never happen" situation, then we should consider panicking if it does. Otherwise, maybe attach the error as an annotation, or log it, or somehow try to alert somebody that things aren't working?

Comment thread pkg/helm/chartproxy/repos.go Outdated
Comment on lines +274 to +276
helmConfig, err := b.unmarshallConfig(item, "", true)
if err != nil {
repoName, _, _ := unstructured.NestedString(item.Object, "metadata", "name")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are you sure you want to ignore the boolean and error return values? Maybe we don't gain enough by looking at them to justify the code and runtime cost...I don't know.

Comment thread pkg/helm/chartproxy/repos.go Outdated
Comment on lines 293 to 305
for _, item := range namespaceRepos.Items {
helmConfig, err := b.unmarshallConfig(item, namespace, false)
if err != nil {
repoName, _, _ := unstructured.NestedString(item.Object, "metadata", "name")
if repoName == "" {
repoName = "<unknown>"
}
klog.Errorf("Error unmarshalling repo %v: %v", item, err)
configErrors = append(configErrors, InvalidRepo{Name: repoName, Error: err.Error()})
continue
}
helmRepos = append(helmRepos, helmConfig)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This code looks ripe for refactoring: I think it's a near duplicate of lines 273-285 which I think can be moved into a helper function.

Comment on lines +303 to +313
if len(configErrors) != len(tt.expectedConfigErrorRepo) {
t.Fatalf("Expected %v config errors, but got %v", len(tt.expectedConfigErrorRepo), len(configErrors))
}
for i, expectedName := range tt.expectedConfigErrorRepo {
if configErrors[i].Name != expectedName {
t.Errorf("Expected config error repo %v but got %v", expectedName, configErrors[i].Name)
}
if configErrors[i].Error == "" {
t.Errorf("Expected non-empty error message for repo %v", expectedName)
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not to disagree with Coderabbitai or anything, but, if this test fails because the counts don't match, the next question that a developer is going to ask is, "What was the mismatch?", and the code isn't going to offer any help. 🫤

Ideally, you would do a "set difference" operation (or two), expecting there to be no difference, and reporting any "extra" ones, either unexpectedly present or absent. Comparing the counts is a quick and easy way to do the check, but it doesn't reveal any helpful information about the failure, which means that the subsequent diagnosis requires reproducing the problem under the debugger, which is potentially cumbersome.

I'll also note that expecting the config errors to come out in a particular order seems fragile at best. (You've finessed this problem by ensuring that there is only ever one error, but you've set the test up to handle multiple...although you don't actually test that.)

I don't have any good suggestions, but I might be inclined to drop the initial count check and to have a nested loop which searches for each expected error in the actual list (instead of assuming and requiring that it show up at a particular index): that would enable reporting any expected ones which were missing. If you put that into a helper function, you could then call it again with the arguments reversed to report any actual ones which weren't in the expected list. This would yield full information without too much code, but it's probably more trouble than it's worth...especially if you only expect one error. 😉 Alternatively, after ensuring that the expected ones were present, you could then use the count-based check to ensure that there weren't any extras...which would at least give you half the information.

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jul 21, 2026
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-gcp-console
/test e2e-playwright

martinszuc and others added 2 commits July 22, 2026 00:04
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Martin Szuc <mszuc@redhat.com>
…rage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Martin Szuc <mszuc@redhat.com>
@martinszuc martinszuc changed the title HELM-586: Show toast notification for invalid Helm Chart repositories HELM-804: Show toast notification for invalid Helm Chart repositories Jul 21, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

@martinszuc: This pull request references HELM-804 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the task to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Analysis / Root cause:

Follow-up to PR #15624 (RFE-7965) which added basicAuth support for ProjectHelmChartRepository. That PR only covered the success case — when a user configures incorrect credentials or a misconfigured Secret (e.g., typo in key name), charts from the affected repository silently disappear from the Developer Catalog with no feedback.

Two gaps existed:

  1. The backend set a console-warning annotation on the aggregated index.yaml response for repos that failed to fetch, but the frontend never read it.
  2. Configuration-level errors (missing Secret keys, missing ConfigMaps, HTTPS required for basicAuth) were silently logged server-side and the repo was dropped before reaching the index fetch stage.

Solution description:

Backend:

  • Improved HTTP error messages in repos.go — 401/403 returns "authentication failed (HTTP %d)" instead of dumping the raw Go response struct. Other non-200 returns "failed to fetch index (HTTP %d)". Added defer resp.Body.Close() to fix a pre-existing resource leak.
  • Updated HelmRepoGetter.List() to return configuration-level errors (missing Secret keys, missing ConfigMaps, HTTPS required) alongside valid repos, instead of silently dropping misconfigured repos.
  • Changed the console-warning annotation from a flat string to a JSON array of {name, error} objects to support frontend i18n.
  • Updated proxy.go to merge both config-level and fetch-level errors into a single annotation.

Frontend:

  • useHelmCharts.tsx now parses the console-warning JSON annotation and displays a danger toast notification via useToast(). The toast appears when the entire Software Catalog is opened (not just the Helm Charts filter), since the index.yaml aggregation runs for all catalog types. Uses a useRef to prevent duplicate toasts on re-renders. Toast is dismissible and auto-dismisses after the default timeout.
  • Added i18n keys for toast title and content.

Tests:

  • Updated TestHelmRepoGetter_ListErrors to assert that misconfigured repos produce the correct configErrors with expected repo names and non-empty error messages.

Screenshots / screen recording:

Auth failure (wrong credentials) — toast on Software Catalog:

scenario1-sw

Auth failure — toast on Helm Charts catalog filter:

scenario1-charts

Unreachable repo — connection timeout error:

unreachable-timeout-1

Config error (typo in Secret key name — usenrame instead of username):

bad-secret

Test setup:

  1. A private HTTPS Helm Chart repository with basic auth is required. Reusable setup scripts are available at openshift-helm/test-scenarios/helm-586-error-notification.
  2. Quick setup:
# Deploy HTTPS + basicAuth Helm repo on an EC2 instance
cd test-scenarios/basic-auth-test
./run-setup.sh <EC2_IP> full

# Apply good-credentials repo to the cluster
oc apply -f /tmp/openshift-helm-repo-setup.yaml

# Create a bad-credentials repo for testing
oc create secret generic helm-bad-auth -n helm-test \
  --from-literal=username=wronguser --from-literal=password=wrongpass
# Then create a ProjectHelmChartRepository pointing at the bad secret
  1. Full step-by-step instructions with all scenarios are documented in the test-scenarios README.

Test cases:

  • Toast appears with auth failure when repository has wrong credentials (401/403)
  • Toast appears with config error when Secret has wrong key names (e.g., usenrame instead of username)
  • Toast appears with connection error when repository URL is unreachable
  • Toast shows multiple errors when multiple repos are misconfigured
  • Toast does not appear after fixing credentials and reloading
  • Toast does not appear for disabled repositories
  • Toast does not appear in namespaces without misconfigured repos
  • Charts from correctly configured repos still load alongside the error toast
  • Toast is dismissible and auto-dismisses after timeout
  • Toast appears on both Software Catalog (all types) and Helm Charts filter

Browser conformance:

  • Chrome
  • Firefox
  • Safari (or Epiphany on Linux)

Additional info:

Reviewers and assignees:

Summary by CodeRabbit

  • New Features
  • Added toast-based notifications for Helm chart repository reachability issues, including a localized summary of unreachable repositories.
  • Bug Fixes
  • Improved Helm chart repository indexing resilience: indexing now continues when some repositories have configuration/access problems, with details surfaced to users.
  • Enhanced error handling for chart index fetching, including clearer behavior for authentication-related HTTP failures.
  • Localization
  • Added new English translation strings to support repository error messaging.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci Bot removed the lgtm Indicates that a PR is ready to be merged. label Jul 21, 2026
@martinszuc

Copy link
Copy Markdown
Contributor Author

/retest

@martinszuc martinszuc changed the title HELM-804: Show toast notification for invalid Helm Chart repositories OCPBUGS-99434: Show toast notification for invalid Helm Chart repositories Jul 22, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. label Jul 22, 2026
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@martinszuc: This pull request references Jira Issue OCPBUGS-99434, which is valid. The bug has been moved to the POST state.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (5.0.0) matches configured target version for branch (5.0.0)
  • bug is in the state New, which is one of the valid states (NEW, ASSIGNED, POST)
Details

In response to this:

Analysis / Root cause:

Follow-up to PR #15624 (RFE-7965) which added basicAuth support for ProjectHelmChartRepository. That PR only covered the success case — when a user configures incorrect credentials or a misconfigured Secret (e.g., typo in key name), charts from the affected repository silently disappear from the Developer Catalog with no feedback.

Two gaps existed:

  1. The backend set a console-warning annotation on the aggregated index.yaml response for repos that failed to fetch, but the frontend never read it.
  2. Configuration-level errors (missing Secret keys, missing ConfigMaps, HTTPS required for basicAuth) were silently logged server-side and the repo was dropped before reaching the index fetch stage.

Solution description:

Backend:

  • Improved HTTP error messages in repos.go — 401/403 returns "authentication failed (HTTP %d)" instead of dumping the raw Go response struct. Other non-200 returns "failed to fetch index (HTTP %d)". Added defer resp.Body.Close() to fix a pre-existing resource leak.
  • Updated HelmRepoGetter.List() to return configuration-level errors (missing Secret keys, missing ConfigMaps, HTTPS required) alongside valid repos, instead of silently dropping misconfigured repos.
  • Changed the console-warning annotation from a flat string to a JSON array of {name, error} objects to support frontend i18n.
  • Updated proxy.go to merge both config-level and fetch-level errors into a single annotation.

Frontend:

  • useHelmCharts.tsx now parses the console-warning JSON annotation and displays a danger toast notification via useToast(). The toast appears when the entire Software Catalog is opened (not just the Helm Charts filter), since the index.yaml aggregation runs for all catalog types. Uses a useRef to prevent duplicate toasts on re-renders. Toast is dismissible and auto-dismisses after the default timeout.
  • Added i18n keys for toast title and content.

Tests:

  • Updated TestHelmRepoGetter_ListErrors to assert that misconfigured repos produce the correct configErrors with expected repo names and non-empty error messages.

Screenshots / screen recording:

Auth failure (wrong credentials) — toast on Software Catalog:

scenario1-sw

Auth failure — toast on Helm Charts catalog filter:

scenario1-charts

Unreachable repo — connection timeout error:

unreachable-timeout-1

Config error (typo in Secret key name — usenrame instead of username):

bad-secret

Test setup:

  1. A private HTTPS Helm Chart repository with basic auth is required. Reusable setup scripts are available at openshift-helm/test-scenarios/helm-586-error-notification.
  2. Quick setup:
# Deploy HTTPS + basicAuth Helm repo on an EC2 instance
cd test-scenarios/basic-auth-test
./run-setup.sh <EC2_IP> full

# Apply good-credentials repo to the cluster
oc apply -f /tmp/openshift-helm-repo-setup.yaml

# Create a bad-credentials repo for testing
oc create secret generic helm-bad-auth -n helm-test \
  --from-literal=username=wronguser --from-literal=password=wrongpass
# Then create a ProjectHelmChartRepository pointing at the bad secret
  1. Full step-by-step instructions with all scenarios are documented in the test-scenarios README.

Test cases:

  • Toast appears with auth failure when repository has wrong credentials (401/403)
  • Toast appears with config error when Secret has wrong key names (e.g., usenrame instead of username)
  • Toast appears with connection error when repository URL is unreachable
  • Toast shows multiple errors when multiple repos are misconfigured
  • Toast does not appear after fixing credentials and reloading
  • Toast does not appear for disabled repositories
  • Toast does not appear in namespaces without misconfigured repos
  • Charts from correctly configured repos still load alongside the error toast
  • Toast is dismissible and auto-dismisses after timeout
  • Toast appears on both Software Catalog (all types) and Helm Charts filter

Browser conformance:

  • Chrome
  • Firefox
  • Safari (or Epiphany on Linux)

Additional info:

Reviewers and assignees:

Summary by CodeRabbit

  • New Features
  • Added toast notifications for Helm chart repository reachability issues, including localized summaries of unreachable repositories.
  • Bug Fixes
  • Improved Helm chart repository indexing resilience: indexing now continues when some repositories have configuration/access problems, and unreachable-repo details are surfaced to users.
  • Enhanced handling of chart index HTTP failures, with clearer authentication-related errors.
  • Localization
  • Added new English translation strings for Helm chart repository error messaging (including unreachable repository lists).

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@webbnh webbnh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

/lgtm

if namespace != "" {
namespaceRepos, err := b.Client.Resource(helmChartRepositoryNamespaceGVK).Namespace(namespace).List(context.TODO(), v1.ListOptions{})
if err != nil {
klog.Errorf("Error listing namespace helm chart repositories: %v \nempty repository list will be used", err)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It hardly matters, but, assuming that helmRepos contains entries from the Cluster/default namespace, it won't be empty when we return it in this error case.

In general, there's very little value in having the log message "predict" what will happen, because, when the log is read, it will have already happened. And, the developer can look at the code where the message was produced and see what it would have done.

So, the second half of this log message is pointless. If you have to make an edit for some other reason, feel free to remove it (here and at line 289, although that one, while also largely pointless, is at least accurate 🙂).

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jul 22, 2026
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-gcp-console
/test e2e-playwright

@openshift-ci

openshift-ci Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: martinszuc, webbnh

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 23, 2026
@openshift-ci

openshift-ci Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

PR needs rebase.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

Error toasts for unreachable Helm Chart repositories should persist
until manually dismissed so users do not miss them.

Signed-off-by: Martin Szuc <mszuc@redhat.com>
@openshift-ci openshift-ci Bot removed the lgtm Indicates that a PR is ready to be merged. label Jul 23, 2026
@openshift-ci

openshift-ci Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

New changes are detected. LGTM label has been removed.

@openshift-ci

openshift-ci Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

@martinszuc: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-playwright 0bcda93 link false /test e2e-playwright
ci/prow/okd-scos-images 43844a5 link true /test okd-scos-images
ci/prow/images 43844a5 link true /test images
ci/prow/backend 43844a5 link true /test backend
ci/prow/analyze 43844a5 link true /test analyze
ci/prow/frontend 43844a5 link true /test frontend
ci/prow/e2e-gcp-console-techpreview 43844a5 link false /test e2e-gcp-console-techpreview
ci/prow/e2e-playwright-techpreview 43844a5 link false /test e2e-playwright-techpreview

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. component/backend Related to backend component/helm Related to helm-plugin jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. kind/i18n Indicates issue or PR relates to internationalization or has content that needs to be translated needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants