Skip to content

OLS console#101

Merged
openshift-merge-bot[bot] merged 6 commits into
openstack-lightspeed:lcore-migrationfrom
Akrog:lcore-console
May 27, 2026
Merged

OLS console#101
openshift-merge-bot[bot] merged 6 commits into
openstack-lightspeed:lcore-migrationfrom
Akrog:lcore-console

Conversation

@Akrog
Copy link
Copy Markdown
Contributor

@Akrog Akrog commented May 7, 2026

Primary objective of this PR is adding the OLS Console deployment to the operator making the Lightspeed console display OpenStack Lightspeed instead of OpenShift Lightspeed.

As part of this work we also:

  • Fix a problem with tests
  • Add a new Make target (kuttl-test-ocp) so it's easy to run kuttl tests on an OCP cluster without uploading to a remote repository (using OCP's internal repository).
  • Fix the console to work when you are using an admin user

Jira: OSPRH-29574
Jira: OSPRH-29746

Summary by CodeRabbit

Release Notes

  • New Features

    • Added OpenShift console plugin integration for Lightspeed UI access.
    • Support for OpenShift internal registry and marketplace deployments.
    • Version-aware console image selection for OpenShift 4.19+ (PatternFly 6) and earlier versions (PatternFly 5).
  • Bug Fixes

    • Updated RBAC permissions for cluster version access.
  • Tests

    • Expanded integration test coverage for console plugin resources and deployment workflows.

Review Change Stack

@openshift-ci openshift-ci Bot requested review from lpiwowar and umago May 7, 2026 16:10
@openshift-ci openshift-ci Bot added the approved label May 7, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ca04a9d7-e832-4e15-bfc2-4b96e67d1211

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds OpenShift console plugin integration to the OpenStack Lightspeed operator. It introduces build infrastructure for OpenShift registries, OCP API dependencies, console image selection by OCP version (PatternFly 5 vs 6), resource builders for Deployment/Service/NetworkPolicy/ConsolePlugin with HTTPS/TLS and locale rewriting, two-phase reconciliation logic with idempotent activation/deactivation, controller wiring, RBAC extensions, and comprehensive unit and KUTTL integration tests.

Changes

Console Plugin Integration

Layer / File(s) Summary
OpenShift Registry and Catalog Build Infrastructure
Makefile, scripts/ocp-registry-push.sh, scripts/ocp-catalog-build.sh
Adds Makefile variables and targets for OpenShift internal registry namespace/endpoint; introduces ocp-registry-push.sh to tag/push images via OpenShift's external route, and ocp-catalog-build.sh to generate catalog indexes via opm and rewrite bundle paths for internal registry compatibility.
Go Module Dependencies and API Imports
go.mod, cmd/main.go, internal/controller/suite_test.go
Promotes k8s.io/{api,apimachinery,client-go} and sigs.k8s.io/yaml to direct dependencies; adds github.com/openshift/api with version pinning; registers OpenShift console/v1 and operator/v1 API schemes in cmd/main.go and test suite for controller-runtime client support.
Console API Types, Constants, and Errors
api/v1beta1/openstacklightspeed_types.go, internal/controller/constants.go, internal/controller/errors.go
Defines ConsoleContainerImage and ConsoleContainerImagePF5 constants for PatternFly 6/5 image defaults; extends OpenStackLightspeedDefaults with ConsoleImageURL and ConsoleImagePF5URL fields populated from environment or constants; exports 10 console plugin resource constants (ConfigMap, Service, Deployment, HTTPS port, plugin name, etc.) and 10 console-related error sentinel variables for reconcile/activation/deletion phases.
Console Resource Builder Functions
internal/controller/console_deployment.go, internal/controller/assets/console_nginx.conf.tmpl, internal/controller/assets/console_locales_rewrite.awk
Implements generateConsoleSelectorLabels, buildConsoleDeploymentSpec with pod security context and rewrite-locales init container running AWK to transform locale JSON from the console image into an EmptyDir, buildConsolePluginSpec wired to the Lightspeed app service with i18n preload and authenticated proxy, buildConsoleNginxConfig for SSL HTTPS port, and buildConsoleNetworkPolicySpec restricting ingress to OpenShift console pods; includes nginx configuration template and AWK script that rewrites OpenShift→OpenStack text variants.
Console Reconciliation and Lifecycle Management
internal/controller/console_reconciler.go
Phase 1 (ReconcileConsoleResources) uses continue-on-error to reconcile ConfigMap, NetworkPolicy, ServiceAccount via CreateOrPatch. Phase 2 (ReconcileConsoleDeployment) uses fail-fast to reconcile Deployment (with OCP 4.19+ → PatternFly 6, OCP <4.19 → PatternFly 5 image selection), Service with serving-certificate annotation, polls TLS Secret for both key and cert, creates/patches cluster ConsolePlugin, then activates by idempotently updating the OpenShift Console CR's spec.plugins list via RetryOnConflict. Deactivation and deletion remove plugin from Console and delete ConsolePlugin CR.
Controller Integration and Ownership Setup
internal/controller/openstacklightspeed_controller.go
Adds consolev1 import and Kubebuilder RBAC for console.openshift.io/consoleplugins and operator.openshift.io/consoles; extends reconcileTasks with ReconcileConsoleResources and ReconcileConsoleDeployment calls; adds DeleteConsolePlugin to deletion task sequence; includes ConsoleUIDeploymentName in readiness deployment checks; updates SetupWithManager to own ConsolePlugin resources so plugin changes trigger reconciliation.
RBAC Permissions, Role, and Operator Metadata
config/rbac/role.yaml, bundle/manifests/openstack-lightspeed-operator.clusterserviceversion.yaml, internal/controller/lcore_reconciler.go
Extends manager-role ClusterRole with rules for console.openshift.io/consoleplugins (full CRUD+watch) and operator.openshift.io/consoles (get/list/update/watch); adds equivalent RBAC rules to CSV spec.install.clusterPermissions; updates reconcileSARRole to grant list verb alongside get on config.openshift.io/clusterversions for version detection.
Console Tests and KUTTL Integration Tests
internal/controller/console_reconciler_test.go, internal/controller/openstacklightspeed_controller_test.go, test/kuttl/common/openstack-lightspeed-instance/errors-openstack-lightspeed-instance.yaml, test/kuttl/tests/update-openstacklightspeed/08-assert-openstacklightspeed-update.yaml
Adds Ginkgo test suite validating selector labels, DeploymentSpec replicas/image/port/volumes/init-container (awk+OpenShift/OpenStack substrings), ConsolePluginSpec backend service/proxy/i18n, nginx config SSL, NetworkPolicy ingress rules, and consoleImageForVersion version-to-image mapping (OCP 4.19+→PF6, <4.19→PF5). Updates controller test to populate LLMEndpoint/LLMEndpointType/ModelName in spec. Adds KUTTL absence assertions for console plugin resources on deletion and presence assertions for ConfigMap/NetworkPolicy/ServiceAccount/Deployment/Service/ConsolePlugin on update.

Sequence Diagram(s)

sequenceDiagram
  participant Controller as OpenStackLightspeed Controller
  participant R1 as ReconcileConsoleResources
  participant R2 as ReconcileConsoleDeployment
  participant K8s as Kubernetes API
  participant Console as OpenShift Console CR
  
  Controller->>R1: Phase 1: Create/Patch base resources
  R1->>K8s: ConfigMap, NetworkPolicy, ServiceAccount
  R1-->>Controller: Continue-on-error
  
  Controller->>R2: Phase 2: Deploy and activate
  R2->>K8s: Detect OCP version, select console image
  R2->>K8s: Deployment + init container (locale rewrite)
  R2->>K8s: Service with serving-certificate annotation
  R2->>K8s: Poll TLS Secret (tls.key, tls.crt)
  R2->>K8s: ConsolePlugin CR
  R2->>Console: Fetch Console CR
  R2->>Console: Add plugin to spec.plugins
  R2->>Console: Update Console CR (activate)
  R2-->>Controller: Fail-fast on error
  
  Console-->>K8s: Plugin visible in OpenShift console UI
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested Labels

lgtm

Suggested Reviewers

  • umago

Poem

🐰 A console appears on the cluster scene,
With locale rewrites, patternfly sheen,
Init containers dance, TLS flows bright,
Version-aware images, OpenShift's new light,
From OpenStack's heart to the web UI's delight! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'OLS console' is vague and overly generic, using non-descriptive terms that don't convey meaningful information about the changeset. Consider using a more specific title like 'Add OpenStack Lightspeed console plugin deployment' or 'Implement console plugin with OpenStack branding and OCP-specific Make targets' to better reflect the main changes.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 95.24% which is sufficient. The required threshold is 80.00%.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@Akrog Akrog changed the title Lcore console OLS console May 7, 2026
@Akrog Akrog force-pushed the lcore-console branch from 3766316 to deb3411 Compare May 7, 2026 16:21
@Akrog Akrog force-pushed the lcore-console branch from deb3411 to 70a5d35 Compare May 8, 2026 11:22
Copy link
Copy Markdown
Contributor

@lpiwowar lpiwowar left a comment

Choose a reason for hiding this comment

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

Overall looks good to me:). I think it is great we will have the logic for automatic build + deployment of the operator for the KUTTL tests. I wrote anything that crossed my mind + I did not test this change manually.

Comment thread cmd/main.go
Comment thread internal/controller/console_deployment.go Outdated
Comment thread internal/controller/console_reconciler.go Outdated
Comment thread Makefile
Comment thread internal/controller/console_reconciler.go
Comment thread internal/controller/console_deployment.go Outdated
@lpiwowar
Copy link
Copy Markdown
Contributor

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@lpiwowar
Copy link
Copy Markdown
Contributor

CodeRabbit does not run by default on the lcore-migration branch. I started it manually by running @coderabbit review.

@openstack-lightspeed openstack-lightspeed deleted a comment from coderabbitai Bot May 12, 2026
@lpiwowar
Copy link
Copy Markdown
Contributor

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
internal/controller/console_deployment.go (1)

112-112: ⚡ Quick win

Verify PullAlways is intentional for production use.

The console plugin deployment uses ImagePullPolicy: PullAlways, which will pull the image on every pod restart. This can cause unnecessary registry load and slower startup times in production environments where images are stable.

Consider using PullIfNotPresent or making the policy configurable unless there's a specific requirement for always pulling the latest image.

🤖 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 `@internal/controller/console_deployment.go` at line 112, The deployment
currently sets ImagePullPolicy to corev1.PullAlways in the console plugin spec;
change this to a safer default (e.g., corev1.PullIfNotPresent) or make the
policy configurable so production doesn’t always re-pull images. Locate the pod
spec building code that sets ImagePullPolicy (reference: ImagePullPolicy and
corev1.PullAlways) and replace the constant with a configurable value (read from
a config struct, flag, or env var) or switch to corev1.PullIfNotPresent as the
default.
internal/controller/console_reconciler.go (1)

154-155: 💤 Low value

Verify version comparison logic for OCP 5+.

The comment states "OCP < 4 can't run this operator, so major != 4 effectively means OCP 5+". However, the condition major != 4 || minor >= 19 will return true for any major version other than 4 (including hypothetical versions less than 4, like 3.x or 2.x).

While the assumption that OCP < 4 won't run this operator is reasonable, the logic should be more explicit for clarity:

♻️ Proposed clarification
 		major, err1 := strconv.Atoi(parts[0])
 		minor, err2 := strconv.Atoi(parts[1])
-		// OCP < 4 can't run this operator, so major != 4 effectively means OCP 5+
-		if err1 == nil && err2 == nil && (major != 4 || minor >= 19) {
+		// Use PF6 for OCP 4.19+ or OCP 5+
+		if err1 == nil && err2 == nil && (major > 4 || (major == 4 && minor >= 19)) {
 			return apiv1beta1.OpenStackLightspeedDefaultValues.ConsoleImageURL
 		}
🤖 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 `@internal/controller/console_reconciler.go` around lines 154 - 155, The
version check in console_reconciler.go using (major != 4 || minor >= 19) is too
broad and matches non-4 older majors; replace that expression with an explicit
test for OCP 4.19+ or any 5+ release: use ((major == 4 && minor >= 19) || major
>= 5) while keeping the surrounding err1/err2 nil checks (the line starting with
if err1 == nil && err2 == nil && ...). This clarifies intent and ensures only
OCP 4.19+ or major >=5 satisfy the condition.
scripts/ocp-catalog-build.sh (1)

44-44: ⚡ Quick win

Use single quotes in trap command.

The trap command should use single quotes to defer variable expansion until the trap executes. Although WORKDIR is set once and doesn't change in this script, single quotes are the recommended practice for trap commands.

🔧 Proposed fix
-trap "rm -rf ${WORKDIR}" EXIT
+trap 'rm -rf ${WORKDIR}' EXIT
🤖 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 `@scripts/ocp-catalog-build.sh` at line 44, Replace the double-quoted trap
invocation so the cleanup command is wrapped in single quotes to defer expansion
of WORKDIR until the trap runs; update the trap invocation that currently reads
trap "rm -rf ${WORKDIR}" to use single quotes and reference the WORKDIR variable
so the removal happens at EXIT with delayed expansion.
🤖 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
`@test/kuttl/common/openstack-lightspeed-instance/assert-openstack-lightspeed-instance.yaml`:
- Around line 151-164: Update the assertion for the Deployment named
lightspeed-console-plugin (and its initContainer rewrite-locales) to enforce
hardened securityContext values: assert pod.spec.securityContext.runAsNonRoot:
true, and for each container/initContainer assert securityContext.runAsNonRoot:
true, securityContext.allowPrivilegeEscalation: false,
securityContext.seccompProfile.type: RuntimeDefault,
securityContext.capabilities.drop: [ALL], and
securityContext.readOnlyRootFilesystem: true where applicable; ensure these
expectations are applied to both the initContainers (rewrite-locales) and the
main containers in the Deployment spec within
assert-openstack-lightspeed-instance.yaml so regressions to default/root-capable
settings are caught.

---

Nitpick comments:
In `@internal/controller/console_deployment.go`:
- Line 112: The deployment currently sets ImagePullPolicy to corev1.PullAlways
in the console plugin spec; change this to a safer default (e.g.,
corev1.PullIfNotPresent) or make the policy configurable so production doesn’t
always re-pull images. Locate the pod spec building code that sets
ImagePullPolicy (reference: ImagePullPolicy and corev1.PullAlways) and replace
the constant with a configurable value (read from a config struct, flag, or env
var) or switch to corev1.PullIfNotPresent as the default.

In `@internal/controller/console_reconciler.go`:
- Around line 154-155: The version check in console_reconciler.go using (major
!= 4 || minor >= 19) is too broad and matches non-4 older majors; replace that
expression with an explicit test for OCP 4.19+ or any 5+ release: use ((major ==
4 && minor >= 19) || major >= 5) while keeping the surrounding err1/err2 nil
checks (the line starting with if err1 == nil && err2 == nil && ...). This
clarifies intent and ensures only OCP 4.19+ or major >=5 satisfy the condition.

In `@scripts/ocp-catalog-build.sh`:
- Line 44: Replace the double-quoted trap invocation so the cleanup command is
wrapped in single quotes to defer expansion of WORKDIR until the trap runs;
update the trap invocation that currently reads trap "rm -rf ${WORKDIR}" to use
single quotes and reference the WORKDIR variable so the removal happens at EXIT
with delayed expansion.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 359e6143-8234-45e4-9fb6-6df39dfb23db

📥 Commits

Reviewing files that changed from the base of the PR and between e49e5a1 and 70a5d35.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (20)
  • Makefile
  • api/v1beta1/openstacklightspeed_types.go
  • bundle/manifests/openstack-lightspeed-operator.clusterserviceversion.yaml
  • cmd/main.go
  • config/rbac/role.yaml
  • go.mod
  • internal/controller/console_deployment.go
  • internal/controller/console_reconciler.go
  • internal/controller/console_reconciler_test.go
  • internal/controller/constants.go
  • internal/controller/errors.go
  • internal/controller/lcore_reconciler.go
  • internal/controller/openstacklightspeed_controller.go
  • internal/controller/openstacklightspeed_controller_test.go
  • internal/controller/suite_test.go
  • scripts/ocp-catalog-build.sh
  • scripts/ocp-registry-push.sh
  • test/kuttl/common/openstack-lightspeed-instance/assert-openstack-lightspeed-instance.yaml
  • test/kuttl/common/openstack-lightspeed-instance/errors-openstack-lightspeed-instance.yaml
  • test/kuttl/tests/update-openstacklightspeed/10-assert-openstacklightspeed-update.yaml

Akrog and others added 5 commits May 25, 2026 18:42
Current code fails on `OpenStackLightspeed Controller When reconciling a
resource [BeforeEach] should successfully reconcile the resource` with
failure `OpenStackLightspeed.lightspeed.openstack.org "test-resource" is
invalid: spec.llmEndpointType: Unsupported value: "": supported values:
"azure_openai", "bam", "openai", "watsonx", "rhoai_vllm", "rhelai_vllm",
"fake_provider"`
lightspeed-stack needs to read the cluster version (via the
config.openshift.io API) when an admin user interacts with it.
Grant list and get on clusterversions to the SAR ClusterRole.

Jira: OSPRH-29574
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Allows running kuttl tests using the OpenShift internal image registry
instead of an external registry like quay.io.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Deploy the OpenShift Lightspeed console plugin as part of the operator
reconciliation loop. Adds the Deployment, Service, ConsolePlugin CR,
nginx ConfigMap, NetworkPolicy, and ServiceAccount using the existing
CreateOrPatch pattern.

Image used for the console depends on the OCP version. Versions prior to
4.19 use one with PatterFly 5 and for later one with PatternFly 6.

Jira: OSPRH-29746
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
To avoid having the console saying it's OpenShift Lightspeed we will be
doing a replacement of the OpenShift word in the internationalization
file.

This mechanism is a bit hacky, but it's a patch that's easy to revert if
we decide to.

Add an init container that rewrites "OpenShift" references to
"OpenStack" in the locales JSON file using awk.

The awk script splits each line at the key-value boundary and only
replaces in values, preserving i18n lookup keys.

Using this mechanism should not be a problem for non English locales (at
least according to Claude), since the i18n fallback mechanism works like
this:

1. This plugin doesn't initialize i18next itself. It relies on the
   parent OpenShift Console (via ConsoleRemotePlugin in
   webpack.config.ts) to set up i18next globally. The plugin just uses
   useTranslation('plugin__lightspeed-console-plugin') to access its
   namespace.
2. When a non-English locale is requested, i18next looks for
   locales/<locale>/plugin__lightspeed-console-plugin.json. Since only
   locales/en/ exists, i18next falls back to English — this is standard
   i18next behavior where missing locale files cause a fallback to the
   default language.
 3. Additionally, the translation keys in
    locales/en/plugin__lightspeed-console-plugin.json are the English
    strings themselves (e.g., "Close": "Close"). So even if the fallback
    mechanism somehow failed entirely, i18next's last resort is to
    display the key as-is — which in this case is already readable
    English text.

As long as OLS console doesn't have a bug in their code that doesn't use
the internationalization with a string and that string has OpenShift in
the wording we should be fine.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Akrog
Copy link
Copy Markdown
Contributor Author

Akrog commented May 25, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@lpiwowar
Copy link
Copy Markdown
Contributor

/retest

Copy link
Copy Markdown
Contributor

@lpiwowar lpiwowar left a comment

Choose a reason for hiding this comment

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

LGTM! Thank you! 👍

  • Waiting for the KUTTL tests to pass.
  • README.md would be nice (but not blocking in the hindsight).

In this patch we update the README.md file to clarify the kuttl related
targets, how they are connected and how they can be used.
@lpiwowar
Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm label May 26, 2026
@lpiwowar lpiwowar self-requested a review May 27, 2026 08:53
@openshift-ci
Copy link
Copy Markdown

openshift-ci Bot commented May 27, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Akrog, lpiwowar

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-merge-bot openshift-merge-bot Bot merged commit 0a68dfd into openstack-lightspeed:lcore-migration May 27, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants