@@ -18,6 +18,7 @@ package controllers
1818
1919import (
2020 "context"
21+ "crypto/x509"
2122 "encoding/json"
2223 "encoding/pem"
2324 "errors"
@@ -426,7 +427,28 @@ func (r *LlamaStackDistributionReconciler) reconcileUserAndCABundleConfigMaps(ct
426427}
427428
428429func (r * LlamaStackDistributionReconciler ) reconcileManagedCABundle (ctx context.Context , instance * llamav1alpha1.LlamaStackDistribution ) error {
430+ logger := log .FromContext (ctx )
431+ managedConfigMapName := getManagedCABundleConfigMapName (instance )
432+
429433 if ! r .hasCABundleConfigMap (instance ) && ! r .hasODHTrustedCABundle (ctx , instance ) {
434+ // No CA bundles configured, delete managed ConfigMap if it exists
435+ existingConfigMap := & corev1.ConfigMap {}
436+ err := r .Get (ctx , types.NamespacedName {
437+ Name : managedConfigMapName ,
438+ Namespace : instance .Namespace ,
439+ }, existingConfigMap )
440+
441+ if err == nil {
442+ // ConfigMap exists but is no longer needed, delete it
443+ logger .Info ("Deleting unused managed CA bundle ConfigMap" , "configMap" , managedConfigMapName )
444+ if delErr := r .Delete (ctx , existingConfigMap ); delErr != nil && ! k8serrors .IsNotFound (delErr ) {
445+ return fmt .Errorf ("failed to delete unused managed CA bundle ConfigMap: %w" , delErr )
446+ }
447+ logger .Info ("Successfully deleted unused managed CA bundle ConfigMap" , "configMap" , managedConfigMapName )
448+ } else if ! k8serrors .IsNotFound (err ) {
449+ // Unexpected error
450+ return fmt .Errorf ("failed to check for managed CA bundle ConfigMap: %w" , err )
451+ }
430452 return nil
431453 }
432454
@@ -1239,9 +1261,9 @@ func (r *LlamaStackDistributionReconciler) hasODHTrustedCABundle(ctx context.Con
12391261
12401262// gatherCABundleData collects all CA certificate data from source ConfigMaps and concatenates them.
12411263// This function implements security measures to prevent injection attacks:
1242- // - Validates all data as valid PEM before processing.
1264+ // - Validates PEM structure and X.509 certificate format during processing.
12431265// - Enforces size limits to prevent resource exhaustion.
1244- // - Only extracts valid CERTIFICATE blocks using PEM decoder.
1266+ // - Only extracts valid CERTIFICATE blocks using PEM decoder and X.509 parser .
12451267func (r * LlamaStackDistributionReconciler ) gatherCABundleData (ctx context.Context , instance * llamav1alpha1.LlamaStackDistribution ) (string , error ) {
12461268 logger := log .FromContext (ctx )
12471269 collector := & certificateCollector {logger : logger }
@@ -1291,10 +1313,20 @@ func (c *certificateCollector) concatenate() (string, error) {
12911313 return "" , errors .New ("failed to find valid certificates in CA bundle ConfigMaps" )
12921314 }
12931315
1294- concatenated := strings .Join (c .certificates , "\n " )
1316+ // Use strings.Builder for efficient memory usage with large bundles
1317+ var builder strings.Builder
1318+ builder .Grow (c .totalSize + len (c .certificates )) // Pre-allocate with space for newlines
1319+ for i , cert := range c .certificates {
1320+ if i > 0 {
1321+ builder .WriteString ("\n " )
1322+ }
1323+ builder .WriteString (cert )
1324+ }
1325+
1326+ concatenated := builder .String ()
12951327 c .logger .Info ("Successfully gathered CA bundle data" ,
12961328 "totalCertificates" , c .certificateCount ,
1297- "totalSize" , c . totalSize )
1329+ "totalSize" , len ( concatenated ) )
12981330
12991331 return concatenated , nil
13001332}
@@ -1324,8 +1356,12 @@ func (r *LlamaStackDistributionReconciler) gatherExplicitCABundle(ctx context.Co
13241356}
13251357
13261358func (r * LlamaStackDistributionReconciler ) gatherODHCABundle (ctx context.Context , instance * llamav1alpha1.LlamaStackDistribution , collector * certificateCollector ) error {
1327- // ODH bundle is optional, so we ignore errors from detection
1328- configMap , keys , _ := r .detectODHTrustedCABundle (ctx , instance )
1359+ configMap , keys , err := r .detectODHTrustedCABundle (ctx , instance )
1360+ if err != nil {
1361+ // Log but don't fail - ODH bundle is optional
1362+ collector .logger .V (1 ).Info ("Could not detect ODH trusted CA bundle" , "error" , err )
1363+ return nil
1364+ }
13291365 if configMap == nil || len (keys ) == 0 {
13301366 return nil
13311367 }
@@ -1378,8 +1414,9 @@ func (r *LlamaStackDistributionReconciler) processODHConfigMapKeys(configMap *co
13781414}
13791415
13801416// extractValidCertificates extracts only valid CERTIFICATE blocks from PEM data.
1381- // This function validates all PEM blocks in the data.
1382- // It filters out non-certificate PEM blocks (e.g., private keys, public keys).
1417+ // This function validates PEM structure and X.509 certificate format for all blocks.
1418+ // It filters out non-certificate PEM blocks (e.g., private keys, public keys) and
1419+ // rejects invalid X.509 certificates.
13831420// Returns: (certificates as strings, total size, certificate count, error).
13841421func extractValidCertificates (data []byte , keyName string ) ([]string , int , int , error ) {
13851422 if len (data ) == 0 {
@@ -1403,6 +1440,11 @@ func extractValidCertificates(data []byte, keyName string) ([]string, int, int,
14031440 continue
14041441 }
14051442
1443+ // Validate that this is actually a valid X.509 certificate
1444+ if _ , err := x509 .ParseCertificate (block .Bytes ); err != nil {
1445+ return nil , 0 , 0 , fmt .Errorf ("failed to parse X.509 certificate from key '%s': %w" , keyName , err )
1446+ }
1447+
14061448 // Re-encode the certificate to ensure it's properly formatted
14071449 certPEM := pem .EncodeToMemory (block )
14081450 if certPEM == nil {
@@ -1476,10 +1518,16 @@ func (r *LlamaStackDistributionReconciler) reconcileManagedCABundleConfigMap(ctx
14761518 // ConfigMap exists, update it if the data has changed
14771519 if existingConfigMap .Data [ManagedCABundleKey ] != caBundleData {
14781520 logger .Info ("Updating managed CA bundle ConfigMap" , "configMap" , managedConfigMapName )
1521+ // Use Patch instead of Update to avoid race conditions
1522+ patch := client .MergeFrom (existingConfigMap .DeepCopy ())
14791523 existingConfigMap .Data = desiredConfigMap .Data
14801524 existingConfigMap .Labels = desiredConfigMap .Labels
1481- if err := r .Update (ctx , existingConfigMap ); err != nil {
1482- return fmt .Errorf ("failed to update managed CA bundle ConfigMap: %w" , err )
1525+ if err := r .Patch (ctx , existingConfigMap , patch ); err != nil {
1526+ if k8serrors .IsConflict (err ) {
1527+ // Conflict detected, will be retried by controller
1528+ return fmt .Errorf ("failed to patch managed CA bundle ConfigMap (conflict): %w" , err )
1529+ }
1530+ return fmt .Errorf ("failed to patch managed CA bundle ConfigMap: %w" , err )
14831531 }
14841532 logger .Info ("Successfully updated managed CA bundle ConfigMap" , "configMap" , managedConfigMapName )
14851533 } else {
0 commit comments