Skip to content

Commit 8299409

Browse files
committed
Adding key field to proxyCA config.
1 parent 5b64139 commit 8299409

File tree

17 files changed

+306
-112
lines changed

17 files changed

+306
-112
lines changed

api/v1alpha1/olsconfig_types.go

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

532547
// 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
@@ -4346,8 +4346,17 @@ spec:
43464346
such as LLM providers.
43474347
properties:
43484348
proxyCACertificate:
4349-
description: The configmap holding proxy CA certificate
4349+
description: |-
4350+
The configmap and key holding proxy CA certificate.
4351+
The key is optional and defaults to "proxy-ca.crt" for backward compatibility.
4352+
If you use a different key name in your ConfigMap, specify it in the Key field of ProxyCACertConfigMapRef.
43504353
properties:
4354+
key:
4355+
default: proxy-ca.crt
4356+
description: |-
4357+
Key in the ConfigMap that contains the proxy CA certificate.
4358+
Defaults to "proxy-ca.crt" if not specified.
4359+
type: string
43514360
name:
43524361
default: ""
43534362
description: |-

internal/controller/appserver/assets.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,15 @@ func GenerateOLSConfigMap(r reconciler.Reconciler, ctx context.Context, cr *olsv
194194
ProxyURL: cr.Spec.OLSConfig.ProxyConfig.ProxyURL,
195195
ProxyCACertPath: "",
196196
}
197-
if cr.Spec.OLSConfig.ProxyConfig.ProxyCACertificateRef != nil && cr.Spec.OLSConfig.ProxyConfig.ProxyCACertificateRef.Name != "" {
198-
err := validateCertificateInConfigMap(r, ctx, cr.Spec.OLSConfig.ProxyConfig.ProxyCACertificateRef.Name, utils.ProxyCACertFileName)
197+
proxyCACertRef := cr.Spec.OLSConfig.ProxyConfig.ProxyCACertificateRef
198+
cmName := utils.GetProxyCACertConfigMapName(proxyCACertRef)
199+
if cmName != "" {
200+
certKey := utils.GetProxyCACertKey(proxyCACertRef)
201+
err := validateCertificateInConfigMap(r, ctx, cmName, certKey)
199202
if err != nil {
200-
return nil, fmt.Errorf("failed to validate proxy CA certificate %s: %w", cr.Spec.OLSConfig.ProxyConfig.ProxyCACertificateRef.Name, err)
203+
return nil, fmt.Errorf("failed to validate proxy CA certificate %s: %w", cmName, err)
201204
}
202-
proxyConfig.ProxyCACertPath = path.Join(utils.OLSAppCertsMountRoot, utils.ProxyCACertVolumeName, utils.ProxyCACertFileName)
205+
proxyConfig.ProxyCACertPath = path.Join(utils.OLSAppCertsMountRoot, utils.ProxyCACertVolumeName, certKey)
203206
}
204207
}
205208

internal/controller/appserver/assets_test.go

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

16381638
Context("Proxy settings", func() {
16391639
const caConfigMapName = "test-ca-configmap"
1640+
const proxyURL = "https://proxy.example.com:8080"
16401641
var proxyCACm *corev1.ConfigMap
16411642

16421643
BeforeEach(func() {
@@ -1710,15 +1711,19 @@ user_data_collector_config: {}
17101711
))
17111712

17121713
cr.Spec.OLSConfig.ProxyConfig = &olsv1alpha1.ProxyConfig{
1713-
ProxyURL: "https://proxy.example.com:8080",
1714-
ProxyCACertificateRef: &corev1.LocalObjectReference{
1715-
Name: caConfigMapName,
1714+
ProxyURL: proxyURL,
1715+
ProxyCACertificateRef: &olsv1alpha1.ProxyCACertConfigMapRef{
1716+
LocalObjectReference: corev1.LocalObjectReference{
1717+
Name: caConfigMapName,
1718+
},
1719+
// No Key specified - tests backward compatibility
17161720
},
17171721
}
17181722

17191723
olsCm, err = GenerateOLSConfigMap(testReconcilerInstance, ctx, cr)
17201724
Expect(err).NotTo(HaveOccurred())
1721-
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"))
1725+
Expect(olsCm.Data[utils.OLSConfigFilename]).To(ContainSubstring("proxy_ca_cert_path: /etc/certs/proxy-ca/" + utils.ProxyCACertFileName))
1726+
Expect(olsCm.Data[utils.OLSConfigFilename]).To(ContainSubstring("proxy_url: " + proxyURL))
17221727

17231728
dep, err = GenerateOLSDeployment(testReconcilerInstance, cr)
17241729
Expect(err).NotTo(HaveOccurred())
@@ -1731,6 +1736,9 @@ user_data_collector_config: {}
17311736
Name: caConfigMapName,
17321737
},
17331738
DefaultMode: &defaultVolumeMode,
1739+
Items: []corev1.KeyToPath{
1740+
{Key: utils.ProxyCACertFileName, Path: utils.ProxyCACertFileName},
1741+
},
17341742
},
17351743
},
17361744
}))
@@ -1749,15 +1757,38 @@ user_data_collector_config: {}
17491757
Expect(err).NotTo(HaveOccurred())
17501758

17511759
cr.Spec.OLSConfig.ProxyConfig = &olsv1alpha1.ProxyConfig{
1752-
ProxyURL: "https://proxy.example.com:8080",
1753-
ProxyCACertificateRef: &corev1.LocalObjectReference{
1754-
Name: caConfigMapName,
1760+
ProxyURL: proxyURL,
1761+
ProxyCACertificateRef: &olsv1alpha1.ProxyCACertConfigMapRef{
1762+
LocalObjectReference: corev1.LocalObjectReference{
1763+
Name: caConfigMapName,
1764+
},
1765+
// No Key specified - tests backward compatibility
17551766
},
17561767
}
17571768
_, err = GenerateOLSConfigMap(testReconcilerInstance, ctx, cr)
17581769
Expect(err).To(HaveOccurred())
17591770
Expect(err.Error()).To(ContainSubstring("failed to validate proxy CA certificate"))
17601771
})
1772+
1773+
It("should use custom Key when ProxyCACertificateRef.Key is set", func() {
1774+
const proxyCertKey = "my-proxy-ca.crt"
1775+
proxyCACm.Data[proxyCertKey] = utils.TestCACert
1776+
err := testReconcilerInstance.Update(ctx, proxyCACm)
1777+
Expect(err).NotTo(HaveOccurred())
1778+
1779+
cr.Spec.OLSConfig.ProxyConfig = &olsv1alpha1.ProxyConfig{
1780+
ProxyURL: proxyURL,
1781+
ProxyCACertificateRef: &olsv1alpha1.ProxyCACertConfigMapRef{
1782+
LocalObjectReference: corev1.LocalObjectReference{Name: caConfigMapName},
1783+
Key: proxyCertKey,
1784+
},
1785+
}
1786+
1787+
olsCm, err := GenerateOLSConfigMap(testReconcilerInstance, ctx, cr)
1788+
Expect(err).NotTo(HaveOccurred())
1789+
Expect(olsCm.Data[utils.OLSConfigFilename]).To(ContainSubstring("proxy_ca_cert_path: /etc/certs/proxy-ca/" + proxyCertKey))
1790+
Expect(olsCm.Data[utils.OLSConfigFilename]).To(ContainSubstring("proxy_url: " + proxyURL))
1791+
})
17611792
})
17621793
})
17631794

internal/controller/appserver/deployment.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,13 +281,18 @@ func GenerateOLSDeployment(r reconciler.Reconciler, cr *olsv1alpha1.OLSConfig) (
281281
// Note: Callback never returns an error, using ForEach for convenient iteration
282282
_ = utils.ForEachExternalConfigMap(cr, func(name, source string) error {
283283
var volumeName, mountPath string
284+
var items []corev1.KeyToPath
284285
switch source {
285286
case "additional-ca":
286287
volumeName = utils.AdditionalCAVolumeName
287288
mountPath = UserCAMountPath
288289
case "proxy-ca":
289290
volumeName = utils.ProxyCACertVolumeName
290291
mountPath = path.Join(utils.OLSAppCertsMountRoot, utils.ProxyCACertVolumeName)
292+
certKey := utils.GetProxyCACertKey(cr.Spec.OLSConfig.ProxyConfig.ProxyCACertificateRef)
293+
items = []corev1.KeyToPath{
294+
{Key: certKey, Path: certKey},
295+
}
291296
default:
292297
return nil
293298
}
@@ -298,6 +303,7 @@ func GenerateOLSDeployment(r reconciler.Reconciler, cr *olsv1alpha1.OLSConfig) (
298303
ConfigMap: &corev1.ConfigMapVolumeSource{
299304
LocalObjectReference: corev1.LocalObjectReference{Name: name},
300305
DefaultMode: &volumeDefaultMode,
306+
Items: items,
301307
},
302308
},
303309
})
@@ -381,13 +387,16 @@ func GenerateOLSDeployment(r reconciler.Reconciler, cr *olsv1alpha1.OLSConfig) (
381387
return nil, fmt.Errorf("failed to get ConfigMap resource version: %w", err)
382388
}
383389

390+
proxyCACMResourceVersion := utils.GetProxyCACertResourceVersion(r, ctx, cr)
391+
384392
deployment := appsv1.Deployment{
385393
ObjectMeta: metav1.ObjectMeta{
386394
Name: utils.OLSAppServerDeploymentName,
387395
Namespace: r.GetNamespace(),
388396
Labels: utils.GenerateAppServerSelectorLabels(),
389397
Annotations: map[string]string{
390-
utils.OLSConfigMapResourceVersionAnnotation: configMapResourceVersion,
398+
utils.OLSConfigMapResourceVersionAnnotation: configMapResourceVersion,
399+
utils.ProxyCACertResourceVersionAnnotation: proxyCACMResourceVersion,
391400
},
392401
},
393402
Spec: appsv1.DeploymentSpec{
@@ -535,14 +544,28 @@ func updateOLSDeployment(r reconciler.Reconciler, ctx context.Context, existingD
535544
}
536545
}
537546

547+
// Step 3: Check if Proxy CA ConfigMap ResourceVersion has changed
548+
storedProxyCACMVersion := existingDeployment.Annotations[utils.ProxyCACertResourceVersionAnnotation]
549+
currentProxyCACMVersion := desiredDeployment.Annotations[utils.ProxyCACertResourceVersionAnnotation]
550+
if storedProxyCACMVersion != currentProxyCACMVersion {
551+
changed = true
552+
}
553+
538554
// If nothing changed, skip update
539555
if !changed {
540556
return nil
541557
}
542558

543559
// Apply changes - always update spec and annotations since something changed
544560
existingDeployment.Spec = desiredDeployment.Spec
561+
562+
// Initialize annotations if nil
563+
if existingDeployment.Annotations == nil {
564+
existingDeployment.Annotations = make(map[string]string)
565+
}
566+
545567
existingDeployment.Annotations[utils.OLSConfigMapResourceVersionAnnotation] = desiredDeployment.Annotations[utils.OLSConfigMapResourceVersionAnnotation]
568+
existingDeployment.Annotations[utils.ProxyCACertResourceVersionAnnotation] = desiredDeployment.Annotations[utils.ProxyCACertResourceVersionAnnotation]
546569

547570
r.GetLogger().Info("updating OLS deployment", "name", existingDeployment.Name)
548571

internal/controller/appserver/reconciler.go

Lines changed: 2 additions & 36 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",
@@ -185,24 +185,6 @@ func reconcileOLSConfigMap(r reconciler.Reconciler, ctx context.Context, cr *ols
185185
return nil
186186
}
187187

188-
func reconcileOLSAdditionalCAConfigMap(r reconciler.Reconciler, ctx context.Context, cr *olsv1alpha1.OLSConfig) error {
189-
if cr.Spec.OLSConfig.AdditionalCAConfigMapRef == nil {
190-
// no additional CA certs, skip
191-
r.GetLogger().Info("Additional CA not configured, reconciliation skipped")
192-
return nil
193-
}
194-
195-
// Verify the configmap exists (annotation is handled by main controller)
196-
cm := &corev1.ConfigMap{}
197-
err := r.Get(ctx, client.ObjectKey{Name: cr.Spec.OLSConfig.AdditionalCAConfigMapRef.Name, Namespace: r.GetNamespace()}, cm)
198-
if err != nil {
199-
return fmt.Errorf("%s: %w", utils.ErrGetAdditionalCACM, err)
200-
}
201-
202-
r.GetLogger().Info("additional CA configmap reconciled", "configmap", cm.Name)
203-
return nil
204-
}
205-
206188
func reconcileExporterConfigMap(r reconciler.Reconciler, ctx context.Context, cr *olsv1alpha1.OLSConfig) error {
207189
// Check if data collector is enabled
208190
enabled, err := dataCollectorEnabled(r, cr)
@@ -247,22 +229,6 @@ func reconcileExporterConfigMap(r reconciler.Reconciler, ctx context.Context, cr
247229
return nil
248230
}
249231

250-
func reconcileProxyCAConfigMap(r reconciler.Reconciler, ctx context.Context, cr *olsv1alpha1.OLSConfig) error {
251-
if cr.Spec.OLSConfig.ProxyConfig == nil || cr.Spec.OLSConfig.ProxyConfig.ProxyCACertificateRef == nil {
252-
// no proxy CA certs, skip
253-
r.GetLogger().Info("Proxy CA not configured, reconciliation skipped")
254-
return nil
255-
}
256-
257-
cm := &corev1.ConfigMap{}
258-
err := r.Get(ctx, client.ObjectKey{Name: cr.Spec.OLSConfig.ProxyConfig.ProxyCACertificateRef.Name, Namespace: r.GetNamespace()}, cm)
259-
if err != nil {
260-
return fmt.Errorf("%s: %w", utils.ErrGetProxyCACM, err)
261-
}
262-
263-
r.GetLogger().Info("proxy CA configmap reconciled", "configmap", cm.Name)
264-
return nil
265-
}
266232

267233
func reconcileServiceAccount(r reconciler.Reconciler, ctx context.Context, cr *olsv1alpha1.OLSConfig) error {
268234
sa, err := GenerateServiceAccount(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)