Skip to content

[OTA-1975] pass products-data cincinnati endpoint to plcc#1429

Open
ankitathomas wants to merge 1 commit into
openshift:mainfrom
ankitathomas:plcc-skill-update
Open

[OTA-1975] pass products-data cincinnati endpoint to plcc#1429
ankitathomas wants to merge 1 commit into
openshift:mainfrom
ankitathomas:plcc-skill-update

Conversation

@ankitathomas

@ankitathomas ankitathomas commented Jul 24, 2026

Copy link
Copy Markdown

Follow-on work to support openshift/cincinnati#1072 and openshift/cincinnati-operator#270

Summary by CodeRabbit

  • New Features

    • Agentic run requests now automatically include the Cincinnati update service URL when available.
    • Added support for discovering the update service endpoint from the platform configuration.
  • Bug Fixes

    • Requests continue to work when the update service or its route cannot be discovered, using a fallback without the URL.
    • Improved formatting of the update path in generated requests.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Walkthrough

Agentic-run synchronization now passes a typed Kubernetes client through discovery, resolves an optional Cincinnati Route URL, and includes it in generated requests. Tests cover discovery failures, URL inclusion, omission, and updated helper signatures.

Changes

Agentic Run Cincinnati URL Integration

Layer / File(s) Summary
Controller client propagation
pkg/agenticrun/controller.go, pkg/agenticrun/controller_test.go
The typed Kubernetes client and context are passed through agentic-run discovery and creation helpers, with existing tests updated for the new signatures.
Cincinnati URL discovery
pkg/agenticrun/controller.go, pkg/agenticrun/controller_test.go
The controller finds the updateservice Service and matching Route, returns an HTTPS host, falls back to an empty URL on errors, and tests successful and missing-resource cases.
Request generation and validation
pkg/agenticrun/controller.go, pkg/agenticrun/controller_test.go
buildRequest formats the update path and conditionally adds the Cincinnati URL, with tests covering both populated and empty values.

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

Sequence Diagram(s)

sequenceDiagram
  participant Sync
  participant getAgenticRun
  participant KubernetesClient
  participant buildRequest
  Sync->>getAgenticRun: pass typed client and context
  getAgenticRun->>KubernetesClient: discover Cincinnati Service and Route
  KubernetesClient-->>getAgenticRun: return Route host or error
  getAgenticRun->>buildRequest: provide Cincinnati URL or empty value
  buildRequest-->>getAgenticRun: return generated request text
Loading

Suggested reviewers: jhadvig


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 getAgenticRun logs Discovered Cincinnati URL: %s, which can expose internal route hostnames in normal logs. Remove the URL from logs or redact it; log only that discovery succeeded/failed, not the hostname/URL itself.
Test Structure And Quality ⚠️ Warning TestGetAgenticRuns_WithReadinessData still passes nil client, but getAgenticRuns now calls discoverCincinnatiURL -> client.List, so the test panics and violates fixture consistency. Pass a fake controller client (or nil-guard discoverCincinnatiURL) in TestGetAgenticRuns_WithReadinessData, and keep discovery setup hoisted once per Sync.
✅ Passed checks (13 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 Test titles are static literals or deterministic table-driven strings; no dynamic names, timestamps, UUIDs, IPs, or generated suffixes found.
Microshift Test Compatibility ✅ Passed Only Go unit tests in pkg/agenticrun/controller_test.go were added; no new Ginkgo e2e tests or MicroShift-unsupported APIs/features appear.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; the changes are standard Go unit tests with no multi-node or HA assumptions.
Topology-Aware Scheduling Compatibility ✅ Passed Only agentic-run request discovery/building changed; no manifests, replicas, node selectors, affinity, or topology spread constraints were added.
Ote Binary Stdout Contract ✅ Passed The PR only changes controller/helper code and a test init for scheme registration; no main/init/TestMain/suite setup stdout writes were added.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo/e2e tests were added; the changes are unit tests with fake clients and no IPv4-only or external connectivity assumptions.
No-Weak-Crypto ✅ Passed No weak crypto, custom crypto, or secret comparisons were added; the PR only changes Cincinnati discovery and request text.
Container-Privileges ✅ Passed Only Go source/tests changed; no container/K8s manifest edits and no privileged/hostNetwork/allowPrivilegeEscalation/SYS_ADMIN settings were added.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: passing the products-data Cincinnati endpoint to PLCC.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@ankitathomas ankitathomas changed the title pass products-data cincinnati endpoint to plcc [OTA-1975] pass products-data cincinnati endpoint to plcc Jul 24, 2026
@openshift-ci

openshift-ci Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: ankitathomas
Once this PR has been reviewed and has the lgtm label, please assign hongkailiu for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found 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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
pkg/agenticrun/controller.go (1)

561-564: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Namespace string duplicated.

"openshift-update-service" is repeated for both the Service and Route lists. Extracting it to a package-level constant would avoid drift if it's ever changed.

Also applies to: 585-586

🤖 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/agenticrun/controller.go` around lines 561 - 564, The namespace string is
duplicated across the service and route listing logic. Define a package-level
constant for "openshift-update-service" and update the Service list and Route
list calls in the controller to use that constant instead of repeating the
literal.
🤖 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/agenticrun/controller.go`:
- Around line 438-449: Move the single `discoverCincinnatiURL` call from
`getAgenticRun` into `getAgenticRuns`, then pass its resolved URL into each
`getAgenticRun` invocation. Update `getAgenticRun` to accept a `cincinnatiURL
string` parameter, remove its unused `client` parameter and discovery block, and
preserve the existing error fallback and request construction behavior.
- Around line 438-449: Guard the discoverCincinnatiURL call in the agentic run
request flow against a nil client before invoking it, preserving the empty
cincinnatiURL fallback and allowing request construction to continue. Use the
existing client variable and keep normal discovery and error logging behavior
unchanged for non-nil clients.

---

Nitpick comments:
In `@pkg/agenticrun/controller.go`:
- Around line 561-564: The namespace string is duplicated across the service and
route listing logic. Define a package-level constant for
"openshift-update-service" and update the Service list and Route list calls in
the controller to use that constant instead of repeating the literal.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: ce315c75-1ea9-4939-b8b4-d7b1616242d5

📥 Commits

Reviewing files that changed from the base of the PR and between 027e419 and 05eac50.

📒 Files selected for processing (2)
  • pkg/agenticrun/controller.go
  • pkg/agenticrun/controller_test.go

Comment on lines +438 to +449
// Discover Cincinnati URL
cincinnatiURL, err := discoverCincinnatiURL(ctx, client)
if err != nil {
klog.V(i.Normal).Infof("Could not discover Cincinnati URL: %v (skills will use public API only)", err)
cincinnatiURL = ""
} else {
klog.V(i.Normal).Infof("Discovered Cincinnati URL: %s", cincinnatiURL)
}

name := agenticRunName(currentVersion, targetVersion)
updateType := classifyUpdate(currentVersion, targetVersion)
request := buildRequest(systemPrompt, currentVersion, targetVersion, channel, updateType, updateKind, availableUpdates, readinessJSON)
request := buildRequest(systemPrompt, currentVersion, targetVersion, channel, updateType, updateKind, availableUpdates, readinessJSON, cincinnatiURL)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

Redundant Cincinnati discovery: called once per update instead of once per Sync.

discoverCincinnatiURL is invoked from getAgenticRun, which runs once per availableUpdate/conditionalUpdate (lines 404, 415). Its result doesn't depend on currentVersion/targetVersion, so with N updates this issues 2N redundant List calls (Services + Routes) against the API server for an identical answer. Hoist the discovery to getAgenticRuns (called once) and pass the resolved cincinnatiURL down, dropping the now-unused client param from getAgenticRun.

♻️ Proposed refactor
 func getAgenticRuns(
 	ctx context.Context,
 	dynamicClient dynamic.Interface,
 	client ctrlruntimeclient.Client,
 	availableUpdates []configv1.Release,
 	conditionalUpdates []configv1.ConditionalUpdate,
 	namespace string,
 	currentVersion, channel,
 	systemPrompt string,
 	skillsImage string,
 ) ([]*agenticrunv1alpha1.AgenticRun, error) {
+	cincinnatiURL, err := discoverCincinnatiURL(ctx, client)
+	if err != nil {
+		klog.V(i.Normal).Infof("Could not discover Cincinnati URL: %v (skills will use public API only)", err)
+		cincinnatiURL = ""
+	} else {
+		klog.V(i.Normal).Infof("Discovered Cincinnati URL: %s", cincinnatiURL)
+	}
+
 	var errs []error
 	var agenticRuns []*agenticrunv1alpha1.AgenticRun
 	for _, au := range availableUpdates {
 		targetVersion := au.Version
 		readinessJSON := runReadinessJSON(ctx, dynamicClient, currentVersion, targetVersion)
-		if agenticRun, err := getAgenticRun(ctx, client, namespace, currentVersion, targetVersion, channel, updateKindRecommended, systemPrompt, readinessJSON, availableUpdates, skillsImage); err != nil {
+		if agenticRun, err := getAgenticRun(ctx, namespace, currentVersion, targetVersion, channel, updateKindRecommended, systemPrompt, readinessJSON, availableUpdates, skillsImage, cincinnatiURL); err != nil {

And drop the client/discovery block from getAgenticRun (lines 426, 438-446), adding a cincinnatiURL string param instead.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Discover Cincinnati URL
cincinnatiURL, err := discoverCincinnatiURL(ctx, client)
if err != nil {
klog.V(i.Normal).Infof("Could not discover Cincinnati URL: %v (skills will use public API only)", err)
cincinnatiURL = ""
} else {
klog.V(i.Normal).Infof("Discovered Cincinnati URL: %s", cincinnatiURL)
}
name := agenticRunName(currentVersion, targetVersion)
updateType := classifyUpdate(currentVersion, targetVersion)
request := buildRequest(systemPrompt, currentVersion, targetVersion, channel, updateType, updateKind, availableUpdates, readinessJSON)
request := buildRequest(systemPrompt, currentVersion, targetVersion, channel, updateType, updateKind, availableUpdates, readinessJSON, cincinnatiURL)
name := agenticRunName(currentVersion, targetVersion)
updateType := classifyUpdate(currentVersion, targetVersion)
request := buildRequest(systemPrompt, currentVersion, targetVersion, channel, updateType, updateKind, availableUpdates, readinessJSON, cincinnatiURL)
🤖 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/agenticrun/controller.go` around lines 438 - 449, Move the single
`discoverCincinnatiURL` call from `getAgenticRun` into `getAgenticRuns`, then
pass its resolved URL into each `getAgenticRun` invocation. Update
`getAgenticRun` to accept a `cincinnatiURL string` parameter, remove its unused
`client` parameter and discovery block, and preserve the existing error fallback
and request construction behavior.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm both call sites pass literal nil for the new client param.
rg -n -B2 -A2 'getAgenticRuns\(' pkg/agenticrun/controller_test.go

Repository: openshift/cluster-version-operator

Length of output: 436


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the helper and its callers, then inspect the relevant slice of controller.go.
rg -n "func discoverCincinnatiURL|discoverCincinnatiURL\(" pkg/agenticrun/controller.go pkg/agenticrun/controller_test.go

echo
echo "---- controller.go excerpt ----"
sed -n '380,470p' pkg/agenticrun/controller.go

echo
echo "---- controller_test.go excerpt around first call site ----"
sed -n '1068,1090p' pkg/agenticrun/controller_test.go

echo
echo "---- controller_test.go excerpt around second call site ----"
sed -n '1288,1310p' pkg/agenticrun/controller_test.go

Repository: openshift/cluster-version-operator

Length of output: 6153


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Probe Go interface semantics for a typed-nil vs truly nil interface call,
# to distinguish panic behavior if the code path reaches client.List on a nil interface.
cat >/tmp/niliface.go <<'PY'
package main

import "fmt"

type C interface{ List() error }

func call(c C) (err error) {
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Errorf("panic: %v", r)
		}
	}()
	return c.List()
}

func main() {
	var c C = nil
	fmt.Printf("%v\n", call(c))
}
PY
go run /tmp/niliface.go

Repository: openshift/cluster-version-operator

Length of output: 244


Guard discoverCincinnatiURL against a nil client

TestGetAgenticRuns_WithReadinessData passes nil for the controller client, and discoverCincinnatiURL calls client.List(...) unconditionally. That panics before the empty-URL fallback can run. Add a nil check here or pass a fake client in the test.

🤖 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/agenticrun/controller.go` around lines 438 - 449, Guard the
discoverCincinnatiURL call in the agentic run request flow against a nil client
before invoking it, preserving the empty cincinnatiURL fallback and allowing
request construction to continue. Use the existing client variable and keep
normal discovery and error logging behavior unchanged for non-nil clients.

@openshift-ci

openshift-ci Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

@ankitathomas: 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/lint 05eac50 link true /test lint
ci/prow/e2e-agnostic-ovn-techpreview-serial-1of3 05eac50 link true /test e2e-agnostic-ovn-techpreview-serial-1of3
ci/prow/e2e-agnostic-ovn-upgrade-into-change 05eac50 link true /test e2e-agnostic-ovn-upgrade-into-change
ci/prow/unit 05eac50 link true /test unit
ci/prow/e2e-agnostic-ovn 05eac50 link true /test e2e-agnostic-ovn
ci/prow/e2e-aws-ovn-techpreview 05eac50 link true /test e2e-aws-ovn-techpreview
ci/prow/e2e-agnostic-ovn-techpreview-serial-3of3 05eac50 link true /test e2e-agnostic-ovn-techpreview-serial-3of3
ci/prow/e2e-hypershift-conformance 05eac50 link true /test e2e-hypershift-conformance
ci/prow/e2e-agnostic-ovn-upgrade-out-of-change 05eac50 link true /test e2e-agnostic-ovn-upgrade-out-of-change

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant