Skip to content

Commit 1d251de

Browse files
committed
Enable OKP support
This commit adds the first step in supporting OKP for OpenStack Lightspeed. Two new configuration sections were added: "okp" and "dev". The "okp" section holds configurations that are more final to the deployment where the "dev" is an easy to way for developers to test the feature while tests/developing it. The options available in "okp" section are: - offline: Whether OKP should be in "offline" mode or not. - accessKey: The OKP access key to decrypt the paid content in the image The options available in the "dev" section are: - featureFlags: This is a list of features that operator wants to expose to be enabled. The value "okp" in the list will deploy OKP. - okpChunkFilterQuery: This is where we can tweak the OKP filter to filter by product, version etc... Signed-off-by: Lucas Alvares Gomes <lucasagomes@gmail.com>
1 parent 34d4f23 commit 1d251de

17 files changed

Lines changed: 551 additions & 11 deletions

api/v1beta1/openstacklightspeed_types.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,44 @@ const (
4545
// ConsoleContainerImagePF5 is the fall-back console image for PatternFly 5 (OCP < 4.19)
4646
ConsoleContainerImagePF5 = "registry.redhat.io/openshift-lightspeed/lightspeed-console-plugin-pf5-rhel9:1.0.12"
4747

48+
// OKPContainerImage is the fall-back container image for OKP (Offline Knowledge Portal)
49+
OKPContainerImage = "registry.redhat.io/offline-knowledge-portal/rhokp-rhel9:latest"
50+
4851
// MaxTokensForResponseDefault is the default maximum number of tokens that should be used for response
4952
MaxTokensForResponseDefault = 2048
5053
)
5154

55+
// DevSpec defines developer/experimental feature configuration.
56+
type DevSpec struct {
57+
// +kubebuilder:validation:Optional
58+
// +kubebuilder:validation:items:Enum=okp
59+
// FeatureFlags is a list of feature flag names to enable experimental features.
60+
// Supported flags: "okp" (Offline Knowledge Portal).
61+
FeatureFlags []string `json:"featureFlags,omitempty"`
62+
63+
// +kubebuilder:validation:Optional
64+
// OKPChunkFilterQuery is a static Solr filter query appended to OKP searches.
65+
// Combined with the default "is_chunk:true" filter using AND.
66+
// Example: "product:*openstack*"
67+
OKPChunkFilterQuery string `json:"okpChunkFilterQuery,omitempty"`
68+
}
69+
70+
// OKPSpec defines configuration for the Offline Knowledge Portal (OKP).
71+
type OKPSpec struct {
72+
// +kubebuilder:validation:Optional
73+
// +kubebuilder:default=true
74+
// Offline controls how source URLs are resolved.
75+
// When true, uses parent_id (offline/Mimir-style).
76+
// When false, uses reference_url (online).
77+
Offline *bool `json:"offline,omitempty"`
78+
79+
// +kubebuilder:validation:Optional
80+
// AccessKey is the name of the Secret containing the access key for the OKP server.
81+
// The secret must contain a key named "access_key".
82+
// An access key can be obtained from https://access.redhat.com/offline/access
83+
AccessKey string `json:"accessKey,omitempty"`
84+
}
85+
5286
// DatabaseSpec defines configuration for persistent PostgreSQL storage.
5387
type DatabaseSpec struct {
5488
// +kubebuilder:validation:Optional
@@ -84,6 +118,15 @@ type OpenStackLightspeedSpec struct {
84118
// When omitted, an emptyDir volume is used (data is lost on pod reschedule).
85119
// When set, a PersistentVolumeClaim is created and mounted.
86120
Database *DatabaseSpec `json:"database,omitempty"`
121+
122+
// +kubebuilder:validation:Optional
123+
// Dev contains developer/experimental feature configuration.
124+
Dev *DevSpec `json:"dev,omitempty"`
125+
126+
// +kubebuilder:validation:Optional
127+
// OKP configures the Offline Knowledge Portal (OKP) RAG source.
128+
// Only used when "okp" is present in dev.featureFlags.
129+
OKP *OKPSpec `json:"okp,omitempty"`
87130
}
88131

89132
// LoggingConfig defines logging configuration for OpenStackLightspeed components
@@ -242,6 +285,7 @@ type OpenStackLightspeedDefaults struct {
242285
PostgresImageURL string
243286
ConsoleImageURL string
244287
ConsoleImagePF5URL string
288+
OKPImageURL string
245289
MaxTokensForResponse int
246290
}
247291

@@ -263,6 +307,8 @@ func SetupDefaults() {
263307
"RELATED_IMAGE_CONSOLE_IMAGE_URL_DEFAULT", ConsoleContainerImage),
264308
ConsoleImagePF5URL: util.GetEnvVar(
265309
"RELATED_IMAGE_CONSOLE_PF5_IMAGE_URL_DEFAULT", ConsoleContainerImagePF5),
310+
OKPImageURL: util.GetEnvVar(
311+
"RELATED_IMAGE_OKP_IMAGE_URL_DEFAULT", OKPContainerImage),
266312
MaxTokensForResponse: MaxTokensForResponseDefault,
267313
}
268314

api/v1beta1/zz_generated.deepcopy.go

Lines changed: 50 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bundle/manifests/lightspeed.openstack.org_openstacklightspeeds.yaml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,25 @@ spec:
6969
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
7070
x-kubernetes-int-or-string: true
7171
type: object
72+
dev:
73+
description: Dev contains developer/experimental feature configuration.
74+
properties:
75+
featureFlags:
76+
description: |-
77+
FeatureFlags is a list of feature flag names to enable experimental features.
78+
Supported flags: "okp" (Offline Knowledge Portal).
79+
items:
80+
enum:
81+
- okp
82+
type: string
83+
type: array
84+
okpChunkFilterQuery:
85+
description: |-
86+
OKPChunkFilterQuery is a static Solr filter query appended to OKP searches.
87+
Combined with the default "is_chunk:true" filter using AND.
88+
Example: "product:*openstack*"
89+
type: string
90+
type: object
7291
enableOCPRAG:
7392
default: false
7493
description: Enables automatic OCP documentation based on cluster
@@ -155,6 +174,25 @@ spec:
155174
Allows forcing a specific OCP version instead of auto-detection.
156175
Format should be like "4.15", "4.16", etc.
157176
type: string
177+
okp:
178+
description: |-
179+
OKP configures the Offline Knowledge Portal (OKP) RAG source.
180+
Only used when "okp" is present in dev.featureFlags.
181+
properties:
182+
accessKey:
183+
description: |-
184+
AccessKey is the name of the Secret containing the access key for the OKP server.
185+
The secret must contain a key named "access_key".
186+
An access key can be obtained from https://access.redhat.com/offline/access
187+
type: string
188+
offline:
189+
default: true
190+
description: |-
191+
Offline controls how source URLs are resolved.
192+
When true, uses parent_id (offline/Mimir-style).
193+
When false, uses reference_url (online).
194+
type: boolean
195+
type: object
158196
ragImage:
159197
description: ContainerImage for the OpenStack Lightspeed RAG container
160198
(will be set to environmental default if empty)

bundle/manifests/openstack-lightspeed-operator.clusterserviceversion.yaml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ metadata:
2525
]
2626
capabilities: Basic Install
2727
categories: AI/Machine Learning
28-
createdAt: "2026-05-28T16:28:23Z"
28+
createdAt: "2026-06-08T12:14:19Z"
2929
description: AI-powered virtual assistant for Red Hat OpenStack Services on OpenShift
3030
features.operators.openshift.io/cnf: "false"
3131
features.operators.openshift.io/cni: "false"
@@ -299,6 +299,8 @@ spec:
299299
value: quay.io/lightspeed-core/lightspeed-to-dataverse-exporter:latest
300300
- name: RELATED_IMAGE_POSTGRES_IMAGE_URL_DEFAULT
301301
value: registry.redhat.io/rhel9/postgresql-16:latest
302+
- name: RELATED_IMAGE_OKP_IMAGE_URL_DEFAULT
303+
value: registry.redhat.io/offline-knowledge-portal/rhokp-rhel9:latest
302304
image: quay.io/openstack-lightspeed/operator:latest
303305
livenessProbe:
304306
httpGet:
@@ -366,6 +368,7 @@ spec:
366368
- ""
367369
resources:
368370
- configmaps
371+
- services
369372
verbs:
370373
- create
371374
- delete
@@ -378,7 +381,6 @@ spec:
378381
- ""
379382
resources:
380383
- persistentvolumeclaims
381-
- services
382384
verbs:
383385
- create
384386
- get
@@ -415,6 +417,7 @@ spec:
415417
- deployments
416418
verbs:
417419
- create
420+
- delete
418421
- get
419422
- list
420423
- patch
@@ -479,4 +482,6 @@ spec:
479482
name: exporter-image-url-default
480483
- image: registry.redhat.io/rhel9/postgresql-16:latest
481484
name: postgres-image-url-default
485+
- image: registry.redhat.io/offline-knowledge-portal/rhokp-rhel9:latest
486+
name: okp-image-url-default
482487
version: 0.0.1

config/crd/bases/lightspeed.openstack.org_openstacklightspeeds.yaml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,25 @@ spec:
6969
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
7070
x-kubernetes-int-or-string: true
7171
type: object
72+
dev:
73+
description: Dev contains developer/experimental feature configuration.
74+
properties:
75+
featureFlags:
76+
description: |-
77+
FeatureFlags is a list of feature flag names to enable experimental features.
78+
Supported flags: "okp" (Offline Knowledge Portal).
79+
items:
80+
enum:
81+
- okp
82+
type: string
83+
type: array
84+
okpChunkFilterQuery:
85+
description: |-
86+
OKPChunkFilterQuery is a static Solr filter query appended to OKP searches.
87+
Combined with the default "is_chunk:true" filter using AND.
88+
Example: "product:*openstack*"
89+
type: string
90+
type: object
7291
enableOCPRAG:
7392
default: false
7493
description: Enables automatic OCP documentation based on cluster
@@ -155,6 +174,25 @@ spec:
155174
Allows forcing a specific OCP version instead of auto-detection.
156175
Format should be like "4.15", "4.16", etc.
157176
type: string
177+
okp:
178+
description: |-
179+
OKP configures the Offline Knowledge Portal (OKP) RAG source.
180+
Only used when "okp" is present in dev.featureFlags.
181+
properties:
182+
accessKey:
183+
description: |-
184+
AccessKey is the name of the Secret containing the access key for the OKP server.
185+
The secret must contain a key named "access_key".
186+
An access key can be obtained from https://access.redhat.com/offline/access
187+
type: string
188+
offline:
189+
default: true
190+
description: |-
191+
Offline controls how source URLs are resolved.
192+
When true, uses parent_id (offline/Mimir-style).
193+
When false, uses reference_url (online).
194+
type: boolean
195+
type: object
158196
ragImage:
159197
description: ContainerImage for the OpenStack Lightspeed RAG container
160198
(will be set to environmental default if empty)

config/manager/manager.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ spec:
8181
value: quay.io/lightspeed-core/lightspeed-to-dataverse-exporter:latest
8282
- name: RELATED_IMAGE_POSTGRES_IMAGE_URL_DEFAULT
8383
value: registry.redhat.io/rhel9/postgresql-16:latest
84+
- name: RELATED_IMAGE_OKP_IMAGE_URL_DEFAULT
85+
value: registry.redhat.io/offline-knowledge-portal/rhokp-rhel9:latest
8486
securityContext:
8587
allowPrivilegeEscalation: false
8688
capabilities:

config/rbac/role.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ rules:
100100
- ""
101101
resources:
102102
- configmaps
103+
- services
103104
verbs:
104105
- create
105106
- delete
@@ -112,7 +113,6 @@ rules:
112113
- ""
113114
resources:
114115
- persistentvolumeclaims
115-
- services
116116
verbs:
117117
- create
118118
- get
@@ -149,6 +149,7 @@ rules:
149149
- deployments
150150
verbs:
151151
- create
152+
- delete
152153
- get
153154
- list
154155
- patch

config/samples/api_v1beta1_openstacklightspeed.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,10 @@ spec:
1515
# database:
1616
# size: "5Gi"
1717
# class: "my-storage-class"
18+
# Uncomment to enable OKP (Offline Knowledge Portal) as an Inline RAG source:
19+
# dev:
20+
# featureFlags:
21+
# - okp
22+
# okpChunkFilterQuery: "product:*openstack*"
23+
# okp:
24+
# accessKey: okp-access-key-secret

hack/env.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ export RELATED_IMAGE_POSTGRES_IMAGE_URL_DEFAULT="registry.redhat.io/rhel9/postgr
66
# the automated pipeline for building OGX-compatible vector database images
77
# is ready.
88
export RELATED_IMAGE_OPENSTACK_LIGHTSPEED_IMAGE_URL_DEFAULT="quay.io/openstack-lightspeed/rag-content:alpha-ogx-os-docs-2025.2"
9+
export RELATED_IMAGE_OKP_IMAGE_URL_DEFAULT="registry.redhat.io/offline-knowledge-portal/rhokp-rhel9:latest"
910
export WATCH_NAMESPACE="openstack-lightspeed"

internal/controller/common.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ import (
2121
_ "embed"
2222
"errors"
2323
"fmt"
24+
"slices"
2425
"strings"
2526

2627
common_helper "github.com/openstack-k8s-operators/lib-common/modules/common/helper"
28+
apiv1beta1 "github.com/openstack-lightspeed/operator/api/v1beta1"
2729
appsv1 "k8s.io/api/apps/v1"
2830
corev1 "k8s.io/api/core/v1"
2931
k8s_errors "k8s.io/apimachinery/pkg/api/errors"
@@ -126,6 +128,24 @@ func isDeploymentReady(deploy *appsv1.Deployment) bool {
126128
deploy.Status.Replicas == replicas
127129
}
128130

131+
// generateOKPSelectorLabels returns selector labels for OKP components.
132+
func generateOKPSelectorLabels() map[string]string {
133+
return map[string]string{
134+
"app.kubernetes.io/component": "okp-server",
135+
"app.kubernetes.io/managed-by": "openstack-lightspeed-operator",
136+
"app.kubernetes.io/name": "openstack-lightspeed-okp-server",
137+
"app.kubernetes.io/part-of": "openstack-lightspeed",
138+
}
139+
}
140+
141+
// isOKPEnabled returns true if the "okp" feature flag is present in dev.featureFlags.
142+
func isOKPEnabled(instance *apiv1beta1.OpenStackLightspeed) bool {
143+
if instance.Spec.Dev == nil {
144+
return false
145+
}
146+
return slices.Contains(instance.Spec.Dev.FeatureFlags, "okp")
147+
}
148+
129149
// getDeployment retrieves deployment from the cluster
130150
func getDeployment(ctx context.Context, h *common_helper.Helper, name string, namespace string) (*appsv1.Deployment, error) {
131151
deployment := &appsv1.Deployment{}

0 commit comments

Comments
 (0)