Skip to content

Commit a322f87

Browse files
authored
fix: Ensure certificates order (#2087)
* fix: Ensure certificates order Signed-off-by: Anatolii Bazko <abazko@redhat.com>
1 parent b5d068b commit a322f87

File tree

4 files changed

+327
-29
lines changed

4 files changed

+327
-29
lines changed

controllers/usernamespace/usernamespace_controller.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ func (r *CheUserNamespaceReconciler) reconcileGitTlsCertificate(ctx context.Cont
460460
return delConfigMap()
461461
}
462462

463-
if gitCert.Data["ca.crt"] == "" {
463+
if gitCert.Data[constants.GitSelfSignedCertsConfigMapCertKey] == "" {
464464
return delConfigMap()
465465
}
466466

@@ -479,12 +479,12 @@ func (r *CheUserNamespaceReconciler) reconcileGitTlsCertificate(ctx context.Cont
479479
}),
480480
},
481481
Data: map[string]string{
482-
"certificate": gitCert.Data["ca.crt"],
482+
"certificate": gitCert.Data[constants.GitSelfSignedCertsConfigMapCertKey],
483483
},
484484
}
485485

486-
if gitCert.Data["githost"] != "" {
487-
target.Data["host"] = gitCert.Data["githost"]
486+
if gitCert.Data[constants.GitSelfSignedCertsConfigMapGitHostKey] != "" {
487+
target.Data["host"] = gitCert.Data[constants.GitSelfSignedCertsConfigMapGitHostKey]
488488
}
489489

490490
_, err := deploy.Sync(deployContext, &target, diffs.ConfigMapAllLabels)

pkg/common/constants/constants.go

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,31 @@ const (
3737
DefaultPluginRegistryCpuRequest = "100m"
3838

3939
// Server
40-
DefaultServerMemoryLimit = "1024Mi"
41-
DefaultServerMemoryRequest = "512Mi"
42-
DefaultServerCpuLimit = "1"
43-
DefaultServerCpuRequest = "100m"
44-
DefaultServerLogLevel = "INFO"
45-
DefaultServerDebug = false
46-
DefaultServerMetricsPort = int32(8087)
47-
DefaultServerDebugPort = int32(8000)
48-
DefaultServerPort = int32(8080)
40+
DefaultServerMemoryLimit = "1024Mi"
41+
DefaultServerMemoryRequest = "512Mi"
42+
DefaultServerCpuLimit = "1"
43+
DefaultServerCpuRequest = "100m"
44+
DefaultServerLogLevel = "INFO"
45+
DefaultServerDebug = false
46+
DefaultServerMetricsPort = int32(8087)
47+
DefaultServerDebugPort = int32(8000)
48+
DefaultServerPort = int32(8080)
49+
DefaultProxyCredentialsSecret = "proxy-credentials"
50+
DefaultJavaOpts = "-XX:MaxRAMPercentage=85.0"
51+
DefaultSecurityContextFsGroup = 1724
52+
DefaultSecurityContextRunAsUser = 1724
53+
DefaultCheServiceAccountName = "che"
54+
55+
// Certificates
4956
DefaultCaBundleCertsCMName = "ca-certs"
50-
DefaultProxyCredentialsSecret = "proxy-credentials"
5157
DefaultGitSelfSignedCertsConfigMapName = "che-git-self-signed-cert"
52-
DefaultJavaOpts = "-XX:MaxRAMPercentage=85.0"
53-
DefaultSecurityContextFsGroup = 1724
54-
DefaultSecurityContextRunAsUser = 1724
55-
DefaultCheServiceAccountName = "che"
58+
// GitSelfSignedCertsConfigMapCertKey is the ConfigMap data key that holds the CA certificate
59+
// in the git self-signed certificates ConfigMap.
60+
GitSelfSignedCertsConfigMapCertKey = "ca.crt"
61+
// GitSelfSignedCertsConfigMapGitHostKey is the ConfigMap data key that holds the git server hostname
62+
// in the git self-signed certificates ConfigMap. This value is not a certificate and must be
63+
// excluded when merging CA bundles.
64+
GitSelfSignedCertsConfigMapGitHostKey = "githost"
5665

5766
// OAuth
5867
BitBucketOAuthConfigClientIdFileName = "id"

pkg/deploy/tls/certificates.go

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ package tls
1515
import (
1616
"errors"
1717
"fmt"
18+
"maps"
1819
"os"
20+
"slices"
1921
"sort"
2022
"strings"
2123

@@ -213,7 +215,7 @@ func (c *CertificatesReconciler) syncGitTrustedCertificates(ctx *chetypes.Deploy
213215
return err == nil, err
214216
}
215217

216-
if gitTrustedCertsCM.Data["ca.crt"] != "" {
218+
if gitTrustedCertsCM.Data[constants.GitSelfSignedCertsConfigMapCertKey] != "" {
217219
gitTrustedCertsCM.TypeMeta = metav1.TypeMeta{
218220
Kind: "ConfigMap",
219221
APIVersion: "v1",
@@ -318,22 +320,27 @@ func (c *CertificatesReconciler) syncCheCABundleCerts(ctx *chetypes.DeployContex
318320
return false, err
319321
}
320322

321-
// Sort configmaps by name, always have the same order and content
322-
// to avoid endless reconcile loop
323+
// Sort ConfigMaps by name and their data keys alphabetically to ensure
324+
// deterministic ordering. This prevents spurious reconcile loops that occur
325+
// when Go's random map iteration produces different output each time.
323326
sort.Slice(cheCABundlesCMs, func(i, j int) bool {
324327
return strings.Compare(cheCABundlesCMs[i].Name, cheCABundlesCMs[j].Name) < 0
325328
})
326329

327-
// Calculated revisions and content
328330
cheCABundlesContent := ""
329331
for _, cm := range cheCABundlesCMs {
330-
for dataKey, dataValue := range cm.Data {
331-
cheCABundlesContent += fmt.Sprintf(
332-
"# ConfigMap: %s, Key: %s\n%s\n\n",
333-
cm.Name,
334-
dataKey,
335-
dataValue,
336-
)
332+
// Sort keys to produce deterministic output and avoid endless reconcile loop
333+
dataKeys := slices.Collect(maps.Keys(cm.Data))
334+
sort.Strings(dataKeys)
335+
336+
for _, dataKey := range dataKeys {
337+
// Skip the "githost" key from the git trusted certs ConfigMap:
338+
// it contains a hostname, not a certificate, and should not be included in the CA bundle.
339+
if dataKey == constants.GitSelfSignedCertsConfigMapGitHostKey && isGitTrustedCertsConfigMap(ctx, &cm) {
340+
continue
341+
}
342+
343+
cheCABundlesContent += printCert(&cm, dataKey)
337344
}
338345
}
339346

@@ -394,3 +401,26 @@ func readKubernetesCaBundle() ([]byte, error) {
394401

395402
return data, nil
396403
}
404+
405+
// printCert formats a single certificate entry with its ConfigMap name and key as a header comment.
406+
func printCert(cm *corev1.ConfigMap, key string) string {
407+
return fmt.Sprintf(
408+
"# ConfigMap: %s, Key: %s\n%s\n\n",
409+
cm.Name,
410+
key,
411+
cm.Data[key],
412+
)
413+
}
414+
415+
func isGitTrustedCertsConfigMap(ctx *chetypes.DeployContext, cm *corev1.ConfigMap) bool {
416+
if cm.Name == constants.DefaultGitSelfSignedCertsConfigMapName {
417+
return true
418+
}
419+
420+
if ctx.CheCluster.Spec.DevEnvironments.TrustedCerts != nil &&
421+
cm.Name == ctx.CheCluster.Spec.DevEnvironments.TrustedCerts.GitTrustedCertsConfigMapName {
422+
return true
423+
}
424+
425+
return false
426+
}

0 commit comments

Comments
 (0)