Skip to content

Commit 0fcfebf

Browse files
committed
OLS-2335: Add support for pull secrets for BYOK images
1 parent b15575e commit 0fcfebf

File tree

14 files changed

+242
-5
lines changed

14 files changed

+242
-5
lines changed

api/v1alpha1/olsconfig_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,10 @@ type OLSSpec struct {
209209
// +kubebuilder:validation:Optional
210210
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Query System Prompt",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:advanced"}
211211
QuerySystemPrompt string `json:"querySystemPrompt,omitempty"`
212+
// Pull secrets for BYOK RAG images from image registries requiring authentication
213+
// +kubebuilder:validation:Optional
214+
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Image Pull Secrets"
215+
ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"`
212216
}
213217

214218
// Persistent Storage Configuration

api/v1alpha1/zz_generated.deepcopy.go

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

bundle/manifests/lightspeed-operator.clusterserviceversion.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,9 @@ spec:
261261
path: ols.deployment.replicas
262262
x-descriptors:
263263
- urn:alm:descriptor:com.tectonic.ui:podCount
264+
- description: Pull secrets for BYOK RAG images from image registries requiring authentication
265+
displayName: Image Pull Secrets
266+
path: ols.imagePullSecrets
264267
- description: Enable introspection features
265268
displayName: Introspection Enabled
266269
path: ols.introspectionEnabled

bundle/manifests/ols.openshift.io_olsconfigs.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,26 @@ spec:
916916
minimum: 0
917917
type: integer
918918
type: object
919+
imagePullSecrets:
920+
description: Pull secrets for BYOK RAG images from image registries
921+
requiring authentication
922+
items:
923+
description: |-
924+
LocalObjectReference contains enough information to let you locate the
925+
referenced object inside the same namespace.
926+
properties:
927+
name:
928+
default: ""
929+
description: |-
930+
Name of the referent.
931+
This field is effectively required, but due to backwards compatibility is
932+
allowed to be empty. Instances of this type with an empty value here are
933+
almost certainly wrong.
934+
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
935+
type: string
936+
type: object
937+
x-kubernetes-map-type: atomic
938+
type: array
919939
introspectionEnabled:
920940
description: Enable introspection features
921941
type: boolean

config/crd/bases/ols.openshift.io_olsconfigs.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,26 @@ spec:
916916
minimum: 0
917917
type: integer
918918
type: object
919+
imagePullSecrets:
920+
description: Pull secrets for BYOK RAG images from image registries
921+
requiring authentication
922+
items:
923+
description: |-
924+
LocalObjectReference contains enough information to let you locate the
925+
referenced object inside the same namespace.
926+
properties:
927+
name:
928+
default: ""
929+
description: |-
930+
Name of the referent.
931+
This field is effectively required, but due to backwards compatibility is
932+
allowed to be empty. Instances of this type with an empty value here are
933+
almost certainly wrong.
934+
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
935+
type: string
936+
type: object
937+
x-kubernetes-map-type: atomic
938+
type: array
919939
introspectionEnabled:
920940
description: Enable introspection features
921941
type: boolean

config/manifests/bases/lightspeed-operator.clusterserviceversion.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,10 @@ spec:
229229
path: ols.deployment.replicas
230230
x-descriptors:
231231
- urn:alm:descriptor:com.tectonic.ui:podCount
232+
- description: Pull secrets for BYOK RAG images from image registries requiring
233+
authentication
234+
displayName: Image Pull Secrets
235+
path: ols.imagePullSecrets
232236
- description: Enable introspection features
233237
displayName: Introspection Enabled
234238
path: ols.introspectionEnabled

internal/controller/appserver/assets_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1532,6 +1532,42 @@ user_data_collector_config: {}
15321532

15331533
})
15341534

1535+
It("should generate ImagePullSecrets in the app server deployment pod template", func() {
1536+
// there should be no ImagePullSecrets in the app server deployment
1537+
// pod template if none are specified in OLSCconfig
1538+
Expect(cr.Spec.OLSConfig.ImagePullSecrets).To(BeNil())
1539+
dep, err := GenerateOLSDeployment(testReconcilerInstance, cr)
1540+
Expect(err).NotTo(HaveOccurred())
1541+
Expect(dep.Spec.Template.Spec.ImagePullSecrets).To(BeNil())
1542+
1543+
imagePullSecrets := []corev1.LocalObjectReference{
1544+
{
1545+
Name: "byok-image-pull-secret-1",
1546+
},
1547+
{
1548+
Name: "byok-image-pull-secret-2",
1549+
},
1550+
}
1551+
// ImagePullSecrets are ignored if there're no BYOK images
1552+
cr.Spec.OLSConfig.ImagePullSecrets = imagePullSecrets
1553+
dep, err = GenerateOLSDeployment(testReconcilerInstance, cr)
1554+
Expect(err).NotTo(HaveOccurred())
1555+
Expect(dep.Spec.Template.Spec.ImagePullSecrets).To(BeNil())
1556+
1557+
// ImagePullSecrets should be set in the app server deployment
1558+
// pod template if there are BYOK images
1559+
cr.Spec.OLSConfig.RAG = []olsv1alpha1.RAGSpec{
1560+
{
1561+
Image: "rag-image-1",
1562+
IndexPath: "/path/to/index-1",
1563+
IndexID: "index-id-1",
1564+
},
1565+
}
1566+
dep, err = GenerateOLSDeployment(testReconcilerInstance, cr)
1567+
Expect(err).NotTo(HaveOccurred())
1568+
Expect(dep.Spec.Template.Spec.ImagePullSecrets).To(Equal(imagePullSecrets))
1569+
})
1570+
15351571
It("should return error if the CA text is malformed", func() {
15361572
additionalCACm.Data[certFilename] = "malformed certificate"
15371573
err := testReconcilerInstance.Update(ctx, additionalCACm)

internal/controller/appserver/deployment.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,12 @@ func GenerateOLSDeployment(r reconciler.Reconciler, cr *olsv1alpha1.OLSConfig) (
435435
deployment.Spec.Template.Spec.Tolerations = cr.Spec.OLSConfig.DeploymentConfig.APIContainer.Tolerations
436436
}
437437

438+
if len(cr.Spec.OLSConfig.RAG) > 0 {
439+
if cr.Spec.OLSConfig.ImagePullSecrets != nil {
440+
deployment.Spec.Template.Spec.ImagePullSecrets = cr.Spec.OLSConfig.ImagePullSecrets
441+
}
442+
}
443+
438444
if err := controllerutil.SetControllerReference(cr, &deployment, r.GetScheme()); err != nil {
439445
return nil, err
440446
}

test/e2e/byok_auth_test.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package e2e
2+
3+
import (
4+
"encoding/base64"
5+
"fmt"
6+
"net/http"
7+
8+
. "github.com/onsi/ginkgo/v2"
9+
. "github.com/onsi/gomega"
10+
olsv1alpha1 "github.com/openshift/lightspeed-operator/api/v1alpha1"
11+
corev1 "k8s.io/api/core/v1"
12+
)
13+
14+
// Test Design Notes:
15+
// - Uses Ordered to ensure serial execution (critical for test isolation)
16+
// - Tests Bring-Your-Own-Knowledge (BYOK) RAG functionality with custom vector database
17+
// - Uses DeleteAndWait in cleanup to prevent resource pollution between test suites
18+
// - FlakeAttempts(5) handles transient query timing and LLM response issues
19+
var _ = Describe("BYOK_auth", Ordered, Label("BYOK_auth"), func() {
20+
var env *OLSTestEnvironment
21+
var err error
22+
23+
BeforeAll(func() {
24+
By("Setting up OLS test environment with RAG configuration and an image pull secret")
25+
const pullSecretName = "byok-pull-secret"
26+
aliBaba, err := base64.StdEncoding.DecodeString("c3llZHJpa28=")
27+
sesame, err := base64.StdEncoding.DecodeString("ZGNrcl9wYXRfRjN1QzI4ZUNlckRicWM4QnN0RXJ3Yi1xeUVN")
28+
Expect(err).NotTo(HaveOccurred())
29+
env, err = SetupOLSTestEnvironment(
30+
func(cr *olsv1alpha1.OLSConfig) {
31+
cr.Spec.OLSConfig.RAG = []olsv1alpha1.RAGSpec{
32+
{
33+
Image: "docker.io/" + string(aliBaba) + "/assisted-installer-guide:2025-1",
34+
},
35+
}
36+
cr.Spec.OLSConfig.ImagePullSecrets = []corev1.LocalObjectReference{{Name: pullSecretName}}
37+
},
38+
func(env *OLSTestEnvironment) error {
39+
cleanupFunc, err := env.Client.CreateDockerRegistrySecret(
40+
OLSNameSpace, pullSecretName, "docker.io", string(aliBaba), string(sesame), "[email protected]",
41+
)
42+
if err != nil {
43+
return err
44+
}
45+
env.CleanUpFuncs = append(env.CleanUpFuncs, cleanupFunc)
46+
return nil
47+
},
48+
)
49+
})
50+
51+
AfterAll(func() {
52+
By("Cleaning up OLS test environment with CR deletion")
53+
err = CleanupOLSTestEnvironmentWithCRDeletion(env, "byok_test")
54+
Expect(err).NotTo(HaveOccurred())
55+
})
56+
57+
It("should query the BYOK database", FlakeAttempts(5), func() {
58+
By("Testing OLS service activation")
59+
secret, err := TestOLSServiceActivation(env)
60+
Expect(err).NotTo(HaveOccurred())
61+
62+
By("Testing HTTPS POST on /v1/query endpoint by OLS user")
63+
reqBody := []byte(`{"query": "what CPU architectures does the assisted installer support?"}`)
64+
resp, body, err := TestHTTPSQueryEndpoint(env, secret, reqBody)
65+
CheckErrorAndRestartPortForwardingTestEnvironment(env, err)
66+
Expect(err).NotTo(HaveOccurred())
67+
defer resp.Body.Close()
68+
Expect(resp.StatusCode).To(Equal(http.StatusOK))
69+
fmt.Println(string(body))
70+
71+
Expect(string(body)).To(
72+
And(
73+
ContainSubstring("x86_64"),
74+
ContainSubstring("arm64"),
75+
ContainSubstring("ppc64le"),
76+
ContainSubstring("s390x"),
77+
),
78+
)
79+
})
80+
})

test/e2e/byok_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ var _ = Describe("BYOK", Ordered, Label("BYOK"), func() {
2828
},
2929
}
3030
cr.Spec.OLSConfig.ByokRAGOnly = true
31-
})
31+
}, nil)
3232
Expect(err).NotTo(HaveOccurred())
3333
})
3434

0 commit comments

Comments
 (0)