Skip to content

Commit b403fd6

Browse files
committed
Adding key field to proxyCA config.
1 parent 99a3bb1 commit b403fd6

16 files changed

Lines changed: 307 additions & 93 deletions

api/v1alpha1/olsconfig_types.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -532,9 +532,24 @@ type ProxyConfig struct {
532532
// +kubebuilder:validation:Pattern=`^https?://.*$`
533533
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Proxy URL"
534534
ProxyURL string `json:"proxyURL,omitempty"`
535-
// The configmap holding proxy CA certificate
535+
// The configmap and key holding proxy CA certificate.
536+
// The key is optional and defaults to "proxy-ca.crt" for backward compatibility.
537+
// If you use a different key name in your ConfigMap, specify it in the Key field of ProxyCACertConfigMapRef.
536538
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Proxy CA Certificate"
537-
ProxyCACertificateRef *corev1.LocalObjectReference `json:"proxyCACertificate,omitempty"`
539+
ProxyCACertificateRef *ProxyCACertConfigMapRef `json:"proxyCACertificate,omitempty"`
540+
}
541+
542+
// ProxyCACertConfigMapRef references a ConfigMap containing the proxy CA certificate.
543+
// Provides backward compatibility by making the key field optional with a default value.
544+
// +structType=atomic
545+
type ProxyCACertConfigMapRef struct {
546+
// The ConfigMap to select from
547+
corev1.LocalObjectReference `json:",inline"`
548+
// Key in the ConfigMap that contains the proxy CA certificate.
549+
// Defaults to "proxy-ca.crt" if not specified.
550+
// +kubebuilder:default="proxy-ca.crt"
551+
// +optional
552+
Key string `json:"key,omitempty"`
538553
}
539554

540555
// ToolFilteringConfig defines configuration for tool filtering using hybrid RAG retrieval.

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 17 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4352,8 +4352,17 @@ spec:
43524352
such as LLM providers.
43534353
properties:
43544354
proxyCACertificate:
4355-
description: The configmap holding proxy CA certificate
4355+
description: |-
4356+
The configmap and key holding proxy CA certificate.
4357+
The key is optional and defaults to "proxy-ca.crt" for backward compatibility.
4358+
If you use a different key name in your ConfigMap, specify it in the Key field of ProxyCACertConfigMapRef.
43564359
properties:
4360+
key:
4361+
default: proxy-ca.crt
4362+
description: |-
4363+
Key in the ConfigMap that contains the proxy CA certificate.
4364+
Defaults to "proxy-ca.crt" if not specified.
4365+
type: string
43574366
name:
43584367
default: ""
43594368
description: |-

internal/controller/appserver/assets.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,12 +183,15 @@ func GenerateOLSConfigMap(r reconciler.Reconciler, ctx context.Context, cr *olsv
183183
ProxyURL: cr.Spec.OLSConfig.ProxyConfig.ProxyURL,
184184
ProxyCACertPath: "",
185185
}
186-
if cr.Spec.OLSConfig.ProxyConfig.ProxyCACertificateRef != nil && cr.Spec.OLSConfig.ProxyConfig.ProxyCACertificateRef.Name != "" {
187-
err := validateCertificateInConfigMap(r, ctx, cr.Spec.OLSConfig.ProxyConfig.ProxyCACertificateRef.Name, utils.ProxyCACertFileName)
186+
proxyCACertRef := cr.Spec.OLSConfig.ProxyConfig.ProxyCACertificateRef
187+
cmName := utils.GetProxyCACertConfigMapName(proxyCACertRef)
188+
if cmName != "" {
189+
certKey := utils.GetProxyCACertKey(proxyCACertRef)
190+
err := validateCertificateInConfigMap(r, ctx, cmName, certKey)
188191
if err != nil {
189-
return nil, fmt.Errorf("failed to validate proxy CA certificate %s: %w", cr.Spec.OLSConfig.ProxyConfig.ProxyCACertificateRef.Name, err)
192+
return nil, fmt.Errorf("failed to validate proxy CA certificate %s: %w", cmName, err)
190193
}
191-
proxyConfig.ProxyCACertPath = path.Join(utils.OLSAppCertsMountRoot, utils.ProxyCACertVolumeName, utils.ProxyCACertFileName)
194+
proxyConfig.ProxyCACertPath = path.Join(utils.OLSAppCertsMountRoot, utils.ProxyCACertVolumeName, certKey)
192195
}
193196
}
194197

internal/controller/appserver/assets_test.go

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1654,6 +1654,7 @@ user_data_collector_config: {}
16541654

16551655
Context("Proxy settings", func() {
16561656
const caConfigMapName = "test-ca-configmap"
1657+
const proxyURL = "https://proxy.example.com:8080"
16571658
var proxyCACm *corev1.ConfigMap
16581659

16591660
BeforeEach(func() {
@@ -1727,15 +1728,19 @@ user_data_collector_config: {}
17271728
))
17281729

17291730
cr.Spec.OLSConfig.ProxyConfig = &olsv1alpha1.ProxyConfig{
1730-
ProxyURL: "https://proxy.example.com:8080",
1731-
ProxyCACertificateRef: &corev1.LocalObjectReference{
1732-
Name: caConfigMapName,
1731+
ProxyURL: proxyURL,
1732+
ProxyCACertificateRef: &olsv1alpha1.ProxyCACertConfigMapRef{
1733+
LocalObjectReference: corev1.LocalObjectReference{
1734+
Name: caConfigMapName,
1735+
},
1736+
// No Key specified - tests backward compatibility
17331737
},
17341738
}
17351739

17361740
olsCm, err = GenerateOLSConfigMap(testReconcilerInstance, ctx, cr)
17371741
Expect(err).NotTo(HaveOccurred())
1738-
Expect(olsCm.Data[utils.OLSConfigFilename]).To(ContainSubstring("proxy_config:\n proxy_ca_cert_path: /etc/certs/proxy-ca/proxy-ca.crt\n proxy_url: https://proxy.example.com:8080\n"))
1742+
Expect(olsCm.Data[utils.OLSConfigFilename]).To(ContainSubstring("proxy_ca_cert_path: /etc/certs/proxy-ca/" + utils.ProxyCACertFileName))
1743+
Expect(olsCm.Data[utils.OLSConfigFilename]).To(ContainSubstring("proxy_url: " + proxyURL))
17391744

17401745
dep, err = GenerateOLSDeployment(testReconcilerInstance, cr)
17411746
Expect(err).NotTo(HaveOccurred())
@@ -1748,6 +1753,9 @@ user_data_collector_config: {}
17481753
Name: caConfigMapName,
17491754
},
17501755
DefaultMode: &defaultVolumeMode,
1756+
Items: []corev1.KeyToPath{
1757+
{Key: utils.ProxyCACertFileName, Path: utils.ProxyCACertFileName},
1758+
},
17511759
},
17521760
},
17531761
}))
@@ -1766,15 +1774,38 @@ user_data_collector_config: {}
17661774
Expect(err).NotTo(HaveOccurred())
17671775

17681776
cr.Spec.OLSConfig.ProxyConfig = &olsv1alpha1.ProxyConfig{
1769-
ProxyURL: "https://proxy.example.com:8080",
1770-
ProxyCACertificateRef: &corev1.LocalObjectReference{
1771-
Name: caConfigMapName,
1777+
ProxyURL: proxyURL,
1778+
ProxyCACertificateRef: &olsv1alpha1.ProxyCACertConfigMapRef{
1779+
LocalObjectReference: corev1.LocalObjectReference{
1780+
Name: caConfigMapName,
1781+
},
1782+
// No Key specified - tests backward compatibility
17721783
},
17731784
}
17741785
_, err = GenerateOLSConfigMap(testReconcilerInstance, ctx, cr)
17751786
Expect(err).To(HaveOccurred())
17761787
Expect(err.Error()).To(ContainSubstring("failed to validate proxy CA certificate"))
17771788
})
1789+
1790+
It("should use custom Key when ProxyCACertificateRef.Key is set", func() {
1791+
const proxyCertKey = "my-proxy-ca.crt"
1792+
proxyCACm.Data[proxyCertKey] = utils.TestCACert
1793+
err := testReconcilerInstance.Update(ctx, proxyCACm)
1794+
Expect(err).NotTo(HaveOccurred())
1795+
1796+
cr.Spec.OLSConfig.ProxyConfig = &olsv1alpha1.ProxyConfig{
1797+
ProxyURL: proxyURL,
1798+
ProxyCACertificateRef: &olsv1alpha1.ProxyCACertConfigMapRef{
1799+
LocalObjectReference: corev1.LocalObjectReference{Name: caConfigMapName},
1800+
Key: proxyCertKey,
1801+
},
1802+
}
1803+
1804+
olsCm, err := GenerateOLSConfigMap(testReconcilerInstance, ctx, cr)
1805+
Expect(err).NotTo(HaveOccurred())
1806+
Expect(olsCm.Data[utils.OLSConfigFilename]).To(ContainSubstring("proxy_ca_cert_path: /etc/certs/proxy-ca/" + proxyCertKey))
1807+
Expect(olsCm.Data[utils.OLSConfigFilename]).To(ContainSubstring("proxy_url: " + proxyURL))
1808+
})
17781809
})
17791810
})
17801811

internal/controller/appserver/deployment.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,13 +266,18 @@ func GenerateOLSDeployment(r reconciler.Reconciler, cr *olsv1alpha1.OLSConfig) (
266266
// Note: Callback never returns an error, using ForEach for convenient iteration
267267
_ = utils.ForEachExternalConfigMap(cr, func(name, source string) error {
268268
var volumeName, mountPath string
269+
var items []corev1.KeyToPath
269270
switch source {
270271
case "additional-ca":
271272
volumeName = utils.AdditionalCAVolumeName
272273
mountPath = UserCAMountPath
273274
case "proxy-ca":
274275
volumeName = utils.ProxyCACertVolumeName
275276
mountPath = path.Join(utils.OLSAppCertsMountRoot, utils.ProxyCACertVolumeName)
277+
certKey := utils.GetProxyCACertKey(cr.Spec.OLSConfig.ProxyConfig.ProxyCACertificateRef)
278+
items = []corev1.KeyToPath{
279+
{Key: certKey, Path: certKey},
280+
}
276281
default:
277282
return nil
278283
}
@@ -283,6 +288,7 @@ func GenerateOLSDeployment(r reconciler.Reconciler, cr *olsv1alpha1.OLSConfig) (
283288
ConfigMap: &corev1.ConfigMapVolumeSource{
284289
LocalObjectReference: corev1.LocalObjectReference{Name: name},
285290
DefaultMode: &volumeDefaultMode,
291+
Items: items,
286292
},
287293
},
288294
})
@@ -367,13 +373,16 @@ func GenerateOLSDeployment(r reconciler.Reconciler, cr *olsv1alpha1.OLSConfig) (
367373
return nil, fmt.Errorf("failed to get ConfigMap resource version: %w", err)
368374
}
369375

376+
proxyCACMResourceVersion := utils.GetProxyCACertResourceVersion(r, ctx, cr)
377+
370378
deployment := appsv1.Deployment{
371379
ObjectMeta: metav1.ObjectMeta{
372380
Name: utils.OLSAppServerDeploymentName,
373381
Namespace: r.GetNamespace(),
374382
Labels: utils.GenerateAppServerSelectorLabels(),
375383
Annotations: map[string]string{
376384
utils.OLSConfigMapResourceVersionAnnotation: configMapResourceVersion,
385+
utils.ProxyCACertResourceVersionAnnotation: proxyCACMResourceVersion,
377386
},
378387
},
379388
Spec: appsv1.DeploymentSpec{
@@ -530,14 +539,28 @@ func updateOLSDeployment(r reconciler.Reconciler, ctx context.Context, existingD
530539
}
531540
}
532541

542+
// Step 3: Check if Proxy CA ConfigMap ResourceVersion has changed
543+
storedProxyCACMVersion := existingDeployment.Annotations[utils.ProxyCACertResourceVersionAnnotation]
544+
currentProxyCACMVersion := desiredDeployment.Annotations[utils.ProxyCACertResourceVersionAnnotation]
545+
if storedProxyCACMVersion != currentProxyCACMVersion {
546+
changed = true
547+
}
548+
533549
// If nothing changed, skip update
534550
if !changed {
535551
return nil
536552
}
537553

538554
// Apply changes - always update spec and annotations since something changed
539555
existingDeployment.Spec = desiredDeployment.Spec
556+
557+
// Initialize annotations if nil
558+
if existingDeployment.Annotations == nil {
559+
existingDeployment.Annotations = make(map[string]string)
560+
}
561+
540562
existingDeployment.Annotations[utils.OLSConfigMapResourceVersionAnnotation] = desiredDeployment.Annotations[utils.OLSConfigMapResourceVersionAnnotation]
563+
existingDeployment.Annotations[utils.ProxyCACertResourceVersionAnnotation] = desiredDeployment.Annotations[utils.ProxyCACertResourceVersionAnnotation]
541564

542565
r.GetLogger().Info("updating OLS deployment", "name", existingDeployment.Name)
543566

internal/controller/appserver/reconciler.go

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func ReconcileAppServerResources(r reconciler.Reconciler, ctx context.Context, o
6464
},
6565
{
6666
Name: "reconcile Additional CA ConfigMap",
67-
Task: reconcileOLSAdditionalCAConfigMap,
67+
Task: utils.ReconcileOLSAdditionalCAConfigMap,
6868
},
6969
{
7070
Name: "reconcile Metrics Reader Secret",
@@ -76,7 +76,7 @@ func ReconcileAppServerResources(r reconciler.Reconciler, ctx context.Context, o
7676
},
7777
{
7878
Name: "reconcile Proxy CA ConfigMap",
79-
Task: reconcileProxyCAConfigMap,
79+
Task: utils.ReconcileProxyCAConfigMap,
8080
},
8181
{
8282
Name: "reconcile ImageStreams",
@@ -189,24 +189,6 @@ func reconcileOLSConfigMap(r reconciler.Reconciler, ctx context.Context, cr *ols
189189
return nil
190190
}
191191

192-
func reconcileOLSAdditionalCAConfigMap(r reconciler.Reconciler, ctx context.Context, cr *olsv1alpha1.OLSConfig) error {
193-
if cr.Spec.OLSConfig.AdditionalCAConfigMapRef == nil {
194-
// no additional CA certs, skip
195-
r.GetLogger().Info("Additional CA not configured, reconciliation skipped")
196-
return nil
197-
}
198-
199-
// Verify the configmap exists (annotation is handled by main controller)
200-
cm := &corev1.ConfigMap{}
201-
err := r.Get(ctx, client.ObjectKey{Name: cr.Spec.OLSConfig.AdditionalCAConfigMapRef.Name, Namespace: r.GetNamespace()}, cm)
202-
if err != nil {
203-
return fmt.Errorf("%s: %w", utils.ErrGetAdditionalCACM, err)
204-
}
205-
206-
r.GetLogger().Info("additional CA configmap reconciled", "configmap", cm.Name)
207-
return nil
208-
}
209-
210192
func reconcileExporterConfigMap(r reconciler.Reconciler, ctx context.Context, cr *olsv1alpha1.OLSConfig) error {
211193
// Check if data collector is enabled
212194
enabled, err := dataCollectorEnabled(r, cr)

internal/controller/appserver/reconciler_test.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -981,8 +981,10 @@ var _ = Describe("App server reconciliator", Ordered, func() {
981981
By("Set up a proxy CA cert")
982982
cr.Spec.OLSConfig.ProxyConfig = &olsv1alpha1.ProxyConfig{
983983
ProxyURL: "https://proxy.example.com:8080",
984-
ProxyCACertificateRef: &corev1.LocalObjectReference{
985-
Name: cmCACertName,
984+
ProxyCACertificateRef: &olsv1alpha1.ProxyCACertConfigMapRef{
985+
LocalObjectReference: corev1.LocalObjectReference{
986+
Name: cmCACertName,
987+
},
986988
},
987989
}
988990
err := ReconcileAppServer(testReconcilerInstance, ctx, cr)
@@ -1008,6 +1010,9 @@ var _ = Describe("App server reconciliator", Ordered, func() {
10081010
Name: cmCACertName,
10091011
},
10101012
DefaultMode: &volumeDefaultMode,
1013+
Items: []corev1.KeyToPath{
1014+
{Key: utils.ProxyCACertFileName, Path: utils.ProxyCACertFileName},
1015+
},
10111016
},
10121017
},
10131018
},

internal/controller/lcore/config.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ func buildLCoreServiceConfig(_ reconciler.Reconciler, cr *olsv1alpha1.OLSConfig)
637637
// color_log: enable colored logs for DEBUG, disable for production (INFO+)
638638
colorLog := logLevel == olsv1alpha1.LogLevelDebug
639639

640-
return map[string]interface{}{
640+
serviceConfig := map[string]interface{}{
641641
"host": "0.0.0.0",
642642
"port": utils.OLSAppServerContainerPort,
643643
"auth_enabled": false,
@@ -651,6 +651,28 @@ func buildLCoreServiceConfig(_ reconciler.Reconciler, cr *olsv1alpha1.OLSConfig)
651651
"tls_key_path": "/etc/certs/lightspeed-tls/tls.key",
652652
},
653653
}
654+
655+
// Add proxy configuration if specified
656+
if cr.Spec.OLSConfig.ProxyConfig != nil {
657+
proxyConfigMap := map[string]interface{}{}
658+
659+
if cr.Spec.OLSConfig.ProxyConfig.ProxyURL != "" {
660+
proxyConfigMap["proxy_url"] = cr.Spec.OLSConfig.ProxyConfig.ProxyURL
661+
}
662+
663+
proxyCACertRef := cr.Spec.OLSConfig.ProxyConfig.ProxyCACertificateRef
664+
cmName := utils.GetProxyCACertConfigMapName(proxyCACertRef)
665+
if cmName != "" {
666+
certKey := utils.GetProxyCACertKey(proxyCACertRef)
667+
proxyConfigMap["proxy_ca_cert_path"] = path.Join(utils.OLSAppCertsMountRoot, utils.ProxyCACertVolumeName, certKey)
668+
}
669+
670+
if len(proxyConfigMap) > 0 {
671+
serviceConfig["proxy_config"] = proxyConfigMap
672+
}
673+
}
674+
675+
return serviceConfig
654676
}
655677

656678
func buildLCoreLlamaStackConfig(r reconciler.Reconciler, _ *olsv1alpha1.OLSConfig) map[string]interface{} {

0 commit comments

Comments
 (0)