Skip to content

feat(#4181): migrate K8s credentials to app-config.yaml - #4184

Open
fullsend-ai-coder[bot] wants to merge 4 commits into
mainfrom
agent/4181-k8s-config-migration
Open

feat(#4181): migrate K8s credentials to app-config.yaml#4184
fullsend-ai-coder[bot] wants to merge 4 commits into
mainfrom
agent/4181-k8s-config-migration

Conversation

@fullsend-ai-coder

Copy link
Copy Markdown
Contributor

Migrate kserve-kubeflow-connector-backend from KubeConfig.loadFromDefault() to config-based K8s authentication following the OCM plugin pattern.

Changes:

  • Remove unused baseUrl from ModelCatalogConfig (entity provider uses
    DiscoveryService.getBaseUrl() exclusively)
  • Merge ConnectorConfig into ReconcilerConfig (eliminate redundant
    intermediate type)
  • Add K8s connection fields (url, serviceAccountToken, skipTLSVerify,
    caData, clusterName) to ReconcilerConfig
  • Implement loadFromOptions() when both url and serviceAccountToken
    are present in app-config; fall back to loadFromDefault() for local
    dev (KUBECONFIG, ~/.kube/config, K8S_TOKEN env var)
  • Add kubernetesPluginRef lookup in plugin.ts to resolve K8s credentials
    from kubernetes.clusterLocatorMethods config (D7 precedence chain)
  • Use safeGetOptionalString wrapper for all optional config reads to
    handle empty env var substitution edge case
  • Replace console.log/error with LoggerService in setupInformer
  • Update config.d.ts with K8s fields (@visibility secret for tokens)
  • Add K8s RBAC example YAML (examples/k8s-rbac.yaml) with minimum
    required permissions (InferenceServices, Routes, ServiceAccounts)
  • Update app-config.yaml with K8s connection fields and commented-out
    kubernetesPluginRef alternative

Note: existing unit tests in catalog-backend-module-model-catalog have pre-existing Babel parser failures unrelated to this change.

Assisted-by: Claude Opus 4.6


Closes #4181

Post-script verification

  • Branch is not main/master (agent/4181-k8s-config-migration)
  • Secret scan passed (gitleaks — c91e22821f3dd7e2daf287e349aeec360eb34c7d..HEAD)
  • Pre-commit hooks passed (authoritative run on runner)
  • Tests ran inside sandbox

Migrate kserve-kubeflow-connector-backend from KubeConfig.loadFromDefault()
to config-based K8s authentication following the OCM plugin pattern.

Changes:
- Remove unused baseUrl from ModelCatalogConfig (entity provider uses
  DiscoveryService.getBaseUrl() exclusively)
- Merge ConnectorConfig into ReconcilerConfig (eliminate redundant
  intermediate type)
- Add K8s connection fields (url, serviceAccountToken, skipTLSVerify,
  caData, clusterName) to ReconcilerConfig
- Implement loadFromOptions() when both url and serviceAccountToken
  are present in app-config; fall back to loadFromDefault() for local
  dev (KUBECONFIG, ~/.kube/config, K8S_TOKEN env var)
- Add kubernetesPluginRef lookup in plugin.ts to resolve K8s credentials
  from kubernetes.clusterLocatorMethods config (D7 precedence chain)
- Use safeGetOptionalString wrapper for all optional config reads to
  handle empty env var substitution edge case
- Replace console.log/error with LoggerService in setupInformer
- Update config.d.ts with K8s fields (@visibility secret for tokens)
- Add K8s RBAC example YAML (examples/k8s-rbac.yaml) with minimum
  required permissions (InferenceServices, Routes, ServiceAccounts)
- Update app-config.yaml with K8s connection fields and commented-out
  kubernetesPluginRef alternative

Note: existing unit tests in catalog-backend-module-model-catalog have
pre-existing Babel parser failures unrelated to this change.

Closes #4181
Assisted-by: Claude Opus 4.6
@fullsend-ai-coder fullsend-ai-coder Bot added the ready-for-review Agent PR ready for human review label Aug 5, 2026
@rhdh-gh-app

rhdh-gh-app Bot commented Aug 5, 2026

Copy link
Copy Markdown

Missing Changesets

The following package(s) are changed by this PR but do not have a changeset:

  • @red-hat-developer-hub/backstage-plugin-catalog-backend-module-model-catalog

See CONTRIBUTING.md for more information about how to add changesets.

Changed Packages

Package Name Package Path Changeset Bump Current Version
@red-hat-developer-hub/backstage-plugin-catalog-backend-module-model-catalog workspaces/ai-integrations/plugins/catalog-backend-module-model-catalog none v0.10.0
@red-hat-developer-hub/backstage-plugin-kserve-kubeflow-connector-backend workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend none v0.1.1

@codecov

codecov Bot commented Aug 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 58.12%. Comparing base (c91e228) to head (38d818e).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4184      +/-   ##
==========================================
- Coverage   58.12%   58.12%   -0.01%     
==========================================
  Files        2422     2422              
  Lines       96493    96486       -7     
  Branches    26884    26882       -2     
==========================================
- Hits        56084    56078       -6     
+ Misses      40207    40206       -1     
  Partials      202      202              
Flag Coverage Δ *Carryforward flag
adoption-insights 84.55% <ø> (ø) Carriedforward from c91e228
ai-integrations 69.57% <100.00%> (-0.19%) ⬇️
app-defaults 69.79% <ø> (ø) Carriedforward from c91e228
augment 46.67% <ø> (ø) Carriedforward from c91e228
boost 76.77% <ø> (ø) Carriedforward from c91e228
bulk-import 72.56% <ø> (ø) Carriedforward from c91e228
cost-management 13.55% <ø> (ø) Carriedforward from c91e228
dcm 60.72% <ø> (ø) Carriedforward from c91e228
extensions 56.59% <ø> (ø) Carriedforward from c91e228
global-floating-action-button 71.18% <ø> (ø) Carriedforward from c91e228
global-header 66.50% <ø> (ø) Carriedforward from c91e228
homepage 47.59% <ø> (ø) Carriedforward from c91e228
install-dynamic-plugins 59.95% <ø> (ø) Carriedforward from c91e228
intelligent-assistant 74.59% <ø> (ø) Carriedforward from c91e228
konflux 91.98% <ø> (ø) Carriedforward from c91e228
lightspeed 69.02% <ø> (ø) Carriedforward from c91e228
mcp-integrations 83.40% <ø> (ø) Carriedforward from c91e228
orchestrator 66.91% <ø> (ø) Carriedforward from c91e228
quickstart 63.74% <ø> (ø) Carriedforward from c91e228
sandbox 79.56% <ø> (ø) Carriedforward from c91e228
scorecard 85.98% <ø> (ø) Carriedforward from c91e228
theme 88.77% <ø> (ø) Carriedforward from c91e228
translations 5.12% <ø> (ø) Carriedforward from c91e228
x2a 79.20% <ø> (ø) Carriedforward from c91e228

*This pull request uses carry forward flags. Click here to find out more.


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c91e228...38d818e. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@gabemontero

Copy link
Copy Markdown
Contributor

/fs-fix run 'yarn prettier:fix' workspace/ai-integrations to fix the failures in CI that manifest from running 'yarn prettier:check'

@fullsend-ai-coder

fullsend-ai-coder Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 8:06 PM UTC · Completed 8:18 PM UTC
Commit: 02e6c2e · View workflow run →

Remove trailing blank line flagged by prettier:check CI gate.

Addresses review feedback on #4184

Assisted-by: Claude Opus 4.6
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 1 (human-triggered)

Fixed prettier formatting in app-config.yaml by removing a trailing blank line. yarn prettier:check now passes.

Fixed (1):

  1. prettier formatting failure in app-config.yaml: Ran prettier --write on app-config.yaml to remove a trailing blank line that caused yarn prettier:check to fail in CI

Tests: passed

Updated by fullsend fix agent

@gabemontero

Copy link
Copy Markdown
Contributor

/fs-review

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 5, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 8:42 PM UTC · Completed 9:01 PM UTC
Commit: 38d818e · View workflow run →

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review

Findings

Medium

  • [pattern-inconsistency] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/src/services/InformerService.ts — The PR converts only a subset of console.log/console.error calls to use the LoggerService parameter. setupInformer now uses logger.info/logger.error/logger.debug, but many other functions in the same file (reconcileInferenceService, innerStart, listInferenceServices, isInferenceServiceReady, getAuthentication, processModelCatalog, fetchModelCardViaAnnotations) still use console.log/console.error. This creates an inconsistent logging idiom within the same file, making operational debugging harder.

  • [missing-changeset] workspaces/ai-integrations/.changeset — The PR does not include a changeset file. The repository's CONTRIBUTING.md states every PR with a change is expected to contain a changeset. This PR modifies the public config schema (config.d.ts), changes plugin initialization, and removes the baseUrl config field — all user-facing changes that should be reflected in changelogs.
    Remediation: Add a changeset file by running yarn changeset from the workspaces/ai-integrations directory, covering both catalog-backend-module-model-catalog (minor: removed baseUrl) and kserve-kubeflow-connector-backend (minor: K8s credentials configurable via app-config.yaml).

  • [config-schema-backward-compatibility] workspaces/ai-integrations/plugins/catalog-backend-module-model-catalog/config.d.ts:23 — The baseUrl field was removed from the config schema. Any downstream deployment that currently sets catalog.providers.modelCatalog.<key>.baseUrl will have that value silently ignored after upgrading. In the prior code, baseUrl was an active fallback for the discovery URL.
    Remediation: Consider adding a startup warning if the old baseUrl field is present in config for one release cycle before full removal, so existing users are informed.

Low

  • [logic-error] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/src/plugin.ts:113 — The authProvider warning check runs unconditionally after the incomplete-fields guard. When kubernetesPluginRef matched but had incomplete K8s fields, the code clears all K8s fields, but the authProvider check fires afterward and may log "proceeding with serviceAccountToken" even though serviceAccountToken was just set to undefined. This produces a misleading log sequence in that edge case.
    Remediation: Move the authProvider check inside the success path so it only fires when the match is usable.

  • [redundant-code] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/src/services/InformerService.ts:264reconcileInferenceService uses inline fallbacks config.defaultOwner || 'default-owner' and config.defaultLifecycle || 'production', but setupInformer already unconditionally sets these fields to non-empty strings. The inline fallbacks are unreachable defense-in-depth.

  • [fail-open] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/src/plugin.ts:24 — The safeGetOptionalString function catches all exceptions and returns undefined. This follows the repository's AGENTS.md-prescribed pattern for handling ConfigReader's TypeError on empty-string env-var substitution. While broader than catching only TypeError, this is the established convention.

  • [data-exposure] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/src/services/InformerService.ts:563 — The cluster API server URL is logged at INFO level during startup. While the URL is not a secret (marked @visibility backend, not @visibility secret), logging infrastructure endpoints is worth noting as standard practice in the Backstage ecosystem.

  • [missing-warning] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/src/services/InformerService.ts:571 — The skipTLSVerify option is passed through to kc.loadFromOptions() with a default of false (good), but no warning is logged when set to true. Disabling TLS verification exposes the service account token to MITM interception.
    Remediation: Log a warning when skipTLSVerify is true.

  • [permission-expansion] workspaces/ai-integrations/examples/k8s-rbac.yaml:42 — The example RBAC YAML defines a ClusterRole with get and list verbs on core serviceaccounts. The code only calls listNamespacedServiceAccount(namespace), but the connector watches InferenceServices cluster-wide, so a ClusterRole is the correct scope for multi-namespace deployments.

  • [pattern-inconsistency] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/src/services/InformerService.tssetupInformer mutates the config parameter in-place (assigning to config.defaultLifecycle, config.defaultOwner, config.serviceAccountToken, etc.). The previous code created a fresh ReconcilerConfig object inside setupInformer. While functional, mutating function parameters can cause surprising behavior at the call site.
    Remediation: Consider constructing a local ReconcilerConfig with merged/defaulted values rather than mutating the passed-in object.

Previous run

Review

Findings

Medium

  • [logic-error] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/src/plugin.ts:149 — The authProvider warning check runs unconditionally after the incomplete-fields check. When the kubernetesPluginRef match is incomplete (url or serviceAccountToken missing), the K8s fields are cleared to undefined at lines 142–145. The authProvider check at line 149 then says "proceeding with serviceAccountToken" but serviceAccountToken may have just been set to undefined, producing a misleading log message.
    Remediation: Move the authProvider check inside the successful-match branch — guard it with a check that reconcilerConfig.url && reconcilerConfig.serviceAccountToken are still set, or move it before the incomplete-fields clearing block.

  • [fail-open] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/src/services/InformerService.ts:598 — When only one of url or serviceAccountToken is provided (partial config), the code falls back to loadFromDefault() with a warning. This is fail-open behavior: a misconfiguration (e.g., a typo in the config key name, or an unset env var) silently downgrades to ambient kubeconfig credentials, which may have broader permissions than the intended service account.
    Remediation: Consider making partial config a hard failure (throw an error), or at minimum upgrade the log from warn to error for production visibility.

  • [missing-doc] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/README.md — The README contains only Backstage CLI boilerplate and no configuration documentation. This PR introduces a substantial new config surface (K8s credentials via url/serviceAccountToken, kubernetesPluginRef for cluster locator lookup, precedence rules, loadFromDefault() fallback). Users have no way to discover how to configure K8s authentication without reading source code.
    Remediation: Add a Configuration section documenting the two config approaches, the precedence chain, a reference to examples/k8s-rbac.yaml, and the loadFromDefault() fallback behavior.

  • [missing-changeset] workspaces/ai-integrations/.changeset — No changeset file was added for breaking changes: removal of baseUrl config field from ModelCatalogConfig, removal of ConnectorConfig export, rename of k8sToken to serviceAccountToken in ReconcilerConfig, and setupInformer signature change.
    Remediation: Add a changeset file for both catalog-backend-module-model-catalog and kserve-kubeflow-connector-backend documenting the breaking changes and new config fields.

Low

  • [edge-case] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/src/plugin.ts:115 — The inner loop over clusters does not break after setting matched = true. If a single clusterLocatorMethod contains multiple clusters with the same name matching kubernetesPluginRef, each subsequent match overwrites the fields. Only the outer locator loop breaks at line 160.
    Remediation: Add a break after the cluster name match block to use the first matching cluster.

  • [test-inadequate] workspaces/ai-integrations/plugins/catalog-backend-module-model-catalog/src/providers/ModelCatalogResourceEntityProvider.test.ts:35 — The test CONFIG was simplified from { baseUrl: 'http://localhost:9090' } to {} but no new test verifies behavior when DiscoveryService.getBaseUrl() returns an empty or unexpected value, since the provider now relies solely on the discovery service.

  • [permission-expansion] workspaces/ai-integrations/examples/k8s-rbac.yaml:19 — The RBAC example defines a ClusterRole granting cluster-wide read access to InferenceServices, Routes, and ServiceAccounts. While the permissions are read-only and match the plugin's operations, operators should be aware this grants visibility into service accounts in every namespace. The example header comments note namespace customization.

  • [inconsistent-logging] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/src/services/InformerService.ts:105 — The PR converts setupInformer logging to LoggerService, but ~46 console.log/error calls remain in the same file (in reconcileInferenceService, innerStart, event handlers, etc.), creating two incompatible logging idioms. This is a reasonable incremental approach scoped to the changed function, but a follow-up to complete the migration would improve consistency.

  • [code-duplication] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/src/plugin.ts:29safeGetOptionalString already exists in catalog-techdoc-url-reader-backend/src/plugin.ts with a slightly different return type. The AGENTS.md documents this as a workspace coding convention (local helper pattern), so duplication is intentional, though a shared utility would reduce drift risk.

  • [parameter-mutation] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/src/services/InformerService.ts:561setupInformer mutates its config parameter in-place (setting defaults, token, clients). The previous implementation created a local config object. While the caller does not reuse the object after the call, the mutation is a hidden data-flow dependency.

  • [scope-deviation] workspaces/ai-integrations/app-config.yaml:128 — The K8s connection fields (url, serviceAccountToken, skipTLSVerify, caData) are commented out in the example config. Both approaches (commented vs. uncommented with empty env var defaults) work correctly since safeGetOptionalString handles the empty-string case. Commenting them out is a reasonable defensive default for a development config.


Labels: PR modifies K8s authentication mechanisms (service account tokens, TLS config, credential precedence) and has a fail-open finding on partial config fallback.

Previous run (2)

Review

Findings

Medium

  • [fail-open] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/src/plugin.ts:155 — The direct config fallback block applies url and serviceAccountToken independently with separate if guards. If only url is present (no token), the partial credential is passed to setupInformer, whose guard (config.url && config.serviceAccountToken) fails, causing fallback to loadFromDefault() — which may connect to a different cluster than the operator intended. setupInformer does log a warning about partial config, but the mismatch originates in plugin.ts where the asymmetry with kubernetesPluginRef validation is most visible. The kubernetesPluginRef path validates both fields together and clears stale fields; the direct config path should do the same.
    Remediation: After applying all direct config fields, add paired validation — if only one of url/serviceAccountToken is present, log a warning and clear both to prevent silent misrouting.

  • [missing-doc] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/README.md — The README contains no configuration documentation. This PR adds significant new config surface (url, serviceAccountToken, skipTLSVerify, caData, kubernetesPluginRef) with two distinct authentication paths. The README should document: the new app-config.yaml fields, the two config approaches (direct fields vs. kubernetesPluginRef), and the K8s RBAC requirements (referencing examples/k8s-rbac.yaml).

Low

  • [stale-reference] workspaces/ai-integrations/plugins/catalog-backend-module-model-catalog/src/providers/ModelCatalogResourceEntityProvider.test.ts:36 — Test config fixture still contains baseUrl: 'http://localhost:9090' which was removed from the ModelCatalogConfig type. The stale key is silently ignored but creates a misleading test fixture.

  • [partial-config-override] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/src/plugin.ts:155skipTLSVerify and caData are applied independently in the direct config fallback even when only one of url/serviceAccountToken is found. These values are harmless without both required fields but create misleading state on the config object. See also: [fail-open] finding at this location.

  • [fail-open] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/src/services/InformerService.ts:575 — The loadFromDefault() fallback is pre-existing behavior and the PR adds an info-level log about it. Operators may benefit from also logging the resolved cluster URL and context name to confirm correct targeting.

  • [naming-consistency] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/src/plugin.ts:30safeGetOptionalString returns string | undefined, while the same-named helper in catalog-techdoc-url-reader-backend returns string (defaulting to ''). The AGENTS.md pattern matches this plugin's variant.

  • [code-organization] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/src/plugin.ts:30safeGetOptionalString defined inline in plugin.ts. The existing codebase also places this helper inline, so this follows the established pattern.

  • [error-handling-idiom] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/src/services/InformerService.ts:649error as Error cast is appropriate for LoggerService.error() which expects Error | JsonObject. The cast is correct but could be replaced with a type guard for robustness.

  • [test-coverage-gap] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/src/plugin.ts — The connector plugin has no test files. The new config logic (kubernetesPluginRef lookup, direct config fallback, loadFromOptions branching) has no automated test coverage.

  • [incomplete-migration] workspaces/ai-integrations/plugins/kserve-kubeflow-connector-backend/src/services/InformerService.ts — Console.log/error migrated to logger in setupInformer, but ~40+ calls remain in other functions. The PR's scope (config migration) doesn't require a full logging overhaul.

  • [config-key-naming] workspaces/ai-integrations/plugins/catalog-backend-module-model-catalog/config.d.ts:31 — New config keys use camelCase (serviceAccountToken, skipTLSVerify) while existing keys use kebab-case (kubeflow-model-catalog-url, default-owner). The camelCase keys match the Backstage kubernetes plugin's config schema, enabling kubernetesPluginRef field-name compatibility.


Labels: Feature PR adding K8s config-based authentication to the ai-integrations workspace kserve connector plugin.

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot added requires-manual-review Review requires human judgment enhancement New feature or request ai-integrations labels Aug 5, 2026
gabemontero and others added 2 commits August 6, 2026 17:27
…~/.kube/config; add namespace comments to k8s rbac example
… baseUrl in test

Medium — direct config fallback applied url and serviceAccountToken
independently. If only one was present, the partial credential passed to
setupInformer where loadFromDefault() could silently connect to the wrong
cluster. Now validates both fields together (matching the kubernetesPluginRef
path) and logs a warning when only one is present.

Low — test fixture had stale baseUrl field removed from ModelCatalogConfig
in this PR. Silently ignored but misleading. Removed.

Signed-off-by: gabemontero <gmontero@redhat.com>
Assisted-by: Claude Opus 4.6
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gabemontero

Copy link
Copy Markdown
Contributor

Fullsend review — addressed

Medium — direct config fallback fail-open (plugin.ts:155):
Fixed. The direct config path now validates url and serviceAccountToken together (same pattern as the kubernetesPluginRef path). If only one is present, a warning is logged and neither is applied — preventing silent misrouting to a different cluster via loadFromDefault().

Low — stale baseUrl in test fixture (ModelCatalogResourceEntityProvider.test.ts:36):
Fixed. Removed the baseUrl: 'http://localhost:9090' field from the test config fixture since baseUrl was removed from ModelCatalogConfig in this PR.

Acknowledged but skipped:

  • [missing-doc] README: Valid — will address in a follow-up. The README update wasn't part of the openspec task scope.
  • [partial-config-override]: Same root cause as the medium finding, covered by that fix.
  • [fail-open] loadFromDefault logging: Pre-existing behavior, nice-to-have. Beyond scope.
  • [naming-consistency] safeGetOptionalString: Follows the AGENTS.md pattern. The url-reader variant intentionally returns '' for a different use case.
  • [code-organization] safeGetOptionalString inline: Follows established pattern in the codebase.
  • [error-handling-idiom] error as Error cast: Cast is correct for LoggerService.error().
  • [test-coverage-gap]: Valid concern — the connector plugin has no tests today. Follow-up.
  • [incomplete-migration] console.log: Task 9 was scoped to setupInformer only, by design.
  • [config-key-naming]: camelCase matches the Backstage kubernetes plugin schema, enabling kubernetesPluginRef field-name compatibility.

Commit: 737e4ae

@sonarqubecloud

sonarqubecloud Bot commented Aug 7, 2026

Copy link
Copy Markdown

gabemontero pushed a commit to gabemontero/rhdh-plugins that referenced this pull request Aug 8, 2026
Remove trailing blank line flagged by prettier:check CI gate.

Addresses review feedback on redhat-developer#4184

Assisted-by: Claude Opus 4.6
@gabemontero

Copy link
Copy Markdown
Contributor

/fs-review

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 8, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 3:39 PM UTC · Completed 4:01 PM UTC

Commit: 737e4ae · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

@gabemontero

Copy link
Copy Markdown
Contributor

Second fullsend review — triage and response

Reviewed all 9 findings from the second fullsend review. Three fixed, six acknowledged with rationale.

Fixed (commit c85d843)

# Severity Finding Fix
1 medium authProvider warning fires even after incomplete-fields branch clears serviceAccountToken Moved authProvider check inside else branch — only warns when match is fully valid
3 low Inner cluster loop doesn't break after name match; duplicate names silently overwrite Added break after cluster name match block
5 low RBAC example uses ClusterRole without noting namespace-scoped alternative Added comment noting operators should consider namespace-scoped Roles/RoleBindings

No change (with rationale)

# Severity Finding Rationale
2 medium Partial config fail-open to loadFromDefault() Intentional design (D7 precedence step 4 in openspec). warn level is appropriate — loadFromDefault() is the expected dev-time fallback. Hard failure would break zero-config dev experience.
4 low No test for empty discovery.getBaseUrl() Our change only removed a stale baseUrl field from the test fixture; DiscoveryService behavior is unchanged and already covered by existing tests.
6 low ~46 console.log calls remain alongside LoggerService Pre-existing throughout InformerService.ts. Converting all of them is a separate cleanup task, not in scope for this PR.
7 low safeGetOptionalString duplicated across plugins Documented as a workspace convention in AGENTS.md. Shared utility is a future refactor.
8 low setupInformer mutates config parameter in-place Config object is created fresh in plugin.ts and never reused — in-place mutation is fine for a fire-once init path.
9 low K8s fields commented out in example app-config.yaml Both direct config (uncommented) and kubernetesPluginRef (commented) approaches are shown. Intentional — operators uncomment whichever approach they use.

@gabemontero

Copy link
Copy Markdown
Contributor

/fs-review

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 8, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 6:42 PM UTC · Completed 7:02 PM UTC

Commit: 737e4ae · View workflow run →

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

Labels

ai-integrations enhancement New feature or request ready-for-review Agent PR ready for human review requires-manual-review Review requires human judgment security workspace/ai-integrations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(ai-integrations): RHIDP-15201: kserve-kubeflow-connector-backend — Migrate K8s Credentials and Plugin Config to app-config.yaml

1 participant