diff --git a/cmd/main.go b/cmd/main.go index c3dd5dd4471..e04f6accdb6 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -312,6 +312,8 @@ func main() { Client: client, Scheme: mgr.GetScheme(), DisableDefaultInstall: strings.ToLower(os.Getenv(common.DisableDefaultInstallEnvVar)) == "true", + TLSMinVersion: string(profile.MinTLSVersion), + TLSCiphers: profile.Ciphers, }).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "GitopsService") os.Exit(1) diff --git a/controllers/gitopsservice_controller.go b/controllers/gitopsservice_controller.go index b643cad0529..25d62d789b6 100644 --- a/controllers/gitopsservice_controller.go +++ b/controllers/gitopsservice_controller.go @@ -146,6 +146,10 @@ type ReconcileGitopsService struct { // disableDefaultInstall, if true, will ensure that the default ArgoCD instance is not instantiated in the openshift-gitops namespace. DisableDefaultInstall bool + // TLSMinVersion is the minimum TLS version to use for the GitOps plugin. + TLSMinVersion string + // TLSCiphers is the list of supported TLS ciphers for the GitOps plugin. + TLSCiphers []string } // +kubebuilder:rbac:groups=config.openshift.io,resources=authentications,verbs=get;list;watch @@ -658,7 +662,7 @@ func (r *ReconcileGitopsService) reconcileBackend(gitopsserviceNamespacedName ty // Define a new backend Deployment { - deploymentObj := newBackendDeployment(gitopsserviceNamespacedName, instance.Spec.ImagePullPolicy) + deploymentObj := newBackendDeployment(gitopsserviceNamespacedName, instance.Spec.ImagePullPolicy, r.TLSMinVersion, r.TLSCiphers) // Add SeccompProfile based on cluster version util.AddSeccompProfileForOpenShift(r.Client, &deploymentObj.Spec.Template.Spec) @@ -796,11 +800,43 @@ func objectMeta(resourceName string, namespace string, opts ...func(*metav1.Obje return objectMeta } -func newBackendDeployment(ns types.NamespacedName, crImagePullPolicy corev1.PullPolicy) *appsv1.Deployment { +func TLSVersionToBackend(tlsVersion string) string { + versionMap := map[string]string{ + "VersionTLS12": "1.2", + "VersionTLS13": "1.3", + "VersionTLS11": "1.1", + "VersionTLS10": "1", + } + if v, ok := versionMap[tlsVersion]; ok { + return v + } + return "" // default fallback +} + +func newBackendDeployment(ns types.NamespacedName, crImagePullPolicy corev1.PullPolicy, TLSMinVersion string, TLSCiphers []string) *appsv1.Deployment { image := os.Getenv(backendImageEnvName) if image == "" { image = backendImage } + env := []corev1.EnvVar{ + { + Name: insecureEnvVar, + Value: insecureEnvVarValue, + }, + } + if TLSVersionToBackend(TLSMinVersion) != "" { + env = append(env, corev1.EnvVar{ + Name: "TLS_MIN_VERSION", + Value: TLSVersionToBackend(TLSMinVersion), + }) + } + + if len(TLSCiphers) > 0 { + env = append(env, corev1.EnvVar{ + Name: "TLS_CIPHER_SUITES", + Value: strings.Join(TLSCiphers, ":"), + }) + } podSpec := corev1.PodSpec{ Containers: []corev1.Container{ { @@ -814,12 +850,7 @@ func newBackendDeployment(ns types.NamespacedName, crImagePullPolicy corev1.Pull ContainerPort: port, // should come from flag }, }, - Env: []corev1.EnvVar{ - { - Name: insecureEnvVar, - Value: insecureEnvVarValue, - }, - }, + Env: env, VolumeMounts: []corev1.VolumeMount{ { MountPath: "/etc/gitops/ssl", diff --git a/controllers/gitopsservice_controller_test.go b/controllers/gitopsservice_controller_test.go index 65860dfeff7..68a6da8f4ae 100644 --- a/controllers/gitopsservice_controller_test.go +++ b/controllers/gitopsservice_controller_test.go @@ -62,7 +62,7 @@ func TestImageFromEnvVariable(t *testing.T) { image := "quay.io/org/test" t.Setenv(backendImageEnvName, image) - deployment := newBackendDeployment(ns, corev1.PullPolicy(corev1.PullIfNotPresent)) + deployment := newBackendDeployment(ns, corev1.PullPolicy(corev1.PullIfNotPresent), "", nil) got := deployment.Spec.Template.Spec.Containers[0].Image if got != image { @@ -70,7 +70,7 @@ func TestImageFromEnvVariable(t *testing.T) { } }) t.Run("env variable for image not found", func(t *testing.T) { - deployment := newBackendDeployment(ns, corev1.PullPolicy(corev1.PullIfNotPresent)) + deployment := newBackendDeployment(ns, corev1.PullPolicy(corev1.PullIfNotPresent), "", nil) got := deployment.Spec.Template.Spec.Containers[0].Image if got != backendImage { @@ -78,6 +78,73 @@ func TestImageFromEnvVariable(t *testing.T) { } }) + t.Run("TLS Min Version 1.3 and empty ciphers", func(t *testing.T) { + deployment := newBackendDeployment(ns, corev1.PullPolicy(corev1.PullIfNotPresent), string(configv1.VersionTLS13), nil) + var gotTLSMinVersion string + for _, env := range deployment.Spec.Template.Spec.Containers[0].Env { + if env.Name == "TLS_MIN_VERSION" { + gotTLSMinVersion = env.Value + break + } + } + if gotTLSMinVersion != "1.3" { + t.Errorf("TLS Min Version mismatch: got %s, want %s", gotTLSMinVersion, "1.3") + } + }) + + t.Run("TLS Min Version 1.2 and empty ciphers", func(t *testing.T) { + deployment := newBackendDeployment(ns, corev1.PullPolicy(corev1.PullIfNotPresent), string(configv1.VersionTLS12), nil) + var gotTLSMinVersion string + for _, env := range deployment.Spec.Template.Spec.Containers[0].Env { + if env.Name == "TLS_MIN_VERSION" { + gotTLSMinVersion = env.Value + break + } + } + if gotTLSMinVersion != "1.2" { + t.Errorf("TLS Min Version mismatch: got %s, want %s", gotTLSMinVersion, "1.2") + } + }) + + t.Run("TLS Min Version 1.3 and single ciphers", func(t *testing.T) { + deployment := newBackendDeployment(ns, corev1.PullPolicy(corev1.PullIfNotPresent), string(configv1.VersionTLS13), []string{"dummy1"}) + var gotTLSMinVersion string + var gotTLSCiphers string + for _, env := range deployment.Spec.Template.Spec.Containers[0].Env { + if env.Name == "TLS_MIN_VERSION" { + gotTLSMinVersion = env.Value + break + } + if env.Name == "TLS_CIPHER_SUITES" { + gotTLSCiphers = env.Value + break + } + } + if gotTLSMinVersion != "1.3" && gotTLSCiphers != "dummy1" { + t.Errorf("TLS Min Version mismatch: got %s, want %s", gotTLSMinVersion, "1.3") + t.Errorf("TLS Cipher mismatch: got %s, want %s", gotTLSCiphers, "dummy1") + } + }) + + t.Run("TLS Min Version 1.3 and double ciphers", func(t *testing.T) { + deployment := newBackendDeployment(ns, corev1.PullPolicy(corev1.PullIfNotPresent), string(configv1.VersionTLS13), []string{"dummy1", "dummy2"}) + var gotTLSMinVersion string + var gotTLSCiphers string + for _, env := range deployment.Spec.Template.Spec.Containers[0].Env { + if env.Name == "TLS_MIN_VERSION" { + gotTLSMinVersion = env.Value + break + } + if env.Name == "TLS_CIPHER_SUITES" { + gotTLSCiphers = env.Value + break + } + } + if gotTLSMinVersion != "1.3" && gotTLSCiphers != "dummy1:dummy2" { + t.Errorf("TLS Min Version mismatch: got %s, want %s", gotTLSMinVersion, "1.3") + t.Errorf("TLS Cipher mismatch: got %s, want %s", gotTLSCiphers, "dummy1:dummy2") + } + }) } func TestReconcileDefaultForArgoCDNodeplacement(t *testing.T) {