Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 25 additions & 5 deletions argocd-operator/controllers/argocd/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -984,7 +984,14 @@ func (r *ReconcileArgoCD) reconcileServerDeployment(cr *argoproj.ArgoCD, useTLSF
if cr.Spec.Server.VolumeMounts != nil {
serverVolumeMounts = append(serverVolumeMounts, cr.Spec.Server.VolumeMounts...)
}
arguments := BuildTLSArgsFromClusterTLSProfile(r.CentralTLSConfigProfile)
// argocd-server does not support --tlscurvepreferences yet; omit curves until a
// supporting image is the default. Keep min version and ciphers.
tlsProfileForServer := r.CentralTLSConfigProfile
tlsProfileForServer.CurvePreferences = nil
arguments, err := BuildTLSArgsFromClusterTLSProfile(tlsProfileForServer, "argocd-server")
if err != nil {
return err
}
deploy.Spec.Template.Spec.Containers = []corev1.Container{{
Args: arguments,
Command: getArgoServerCommand(cr, useTLSForRedis),
Expand Down Expand Up @@ -1329,11 +1336,14 @@ func (r *ReconcileArgoCD) reconcileServerDeployment(cr *argoproj.ArgoCD, useTLSF
return r.Create(context.TODO(), deploy)
}

// BuildTLSArgsFromClusterTLSProfile builds the command line arguments for the ArgoCD components based on the cluster's TLS profile configuration.
func BuildTLSArgsFromClusterTLSProfile(centralTLSConfig tlsProfile.TLSConfigProfile) []string {
// BuildTLSArgsFromClusterTLSProfile builds the command line arguments for Argo CD
// components based on the cluster's TLS profile configuration.
// component identifies the caller in curve-preference error/log messages
// (e.g. "argocd-server", "argocd-repo-server", "argocd-image-updater").
func BuildTLSArgsFromClusterTLSProfile(centralTLSConfig tlsProfile.TLSConfigProfile, component string) ([]string, error) {
var args []string
if centralTLSConfig.DisableClusterTLSProfile {
return nil
return nil, nil
}
if v := argoutil.TLSProtocolVersionString(centralTLSConfig.MinVersion); v != "" {
args = append(args, "--tlsminversion", v)
Expand All @@ -1359,7 +1369,17 @@ func BuildTLSArgsFromClusterTLSProfile(centralTLSConfig tlsProfile.TLSConfigProf
args = append(args, "--tlsciphers", strings.Join(ciphers, ":"))
}
}
return args
curves, err := argoutil.MapOpenShiftTLSGroupsToGoCurves(centralTLSConfig.CurvePreferences, component)
if err != nil {
// Do not fail reconciliation for incompatible curve preferences. Keep min
// version/ciphers and fall back to the component's default curve selection
// so disable/delete paths (and other reconcile work) can still proceed.
log.Info("skipping TLS curve preferences; falling back to component defaults",
"component", component, "error", err.Error())
} else if curves != "" {
args = append(args, "--tlscurvepreferences", curves)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
return args, nil
}

// triggerDeploymentRollout will update the label with the given key to trigger a new rollout of the Deployment.
Expand Down
53 changes: 51 additions & 2 deletions argocd-operator/controllers/argocd/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3497,11 +3497,49 @@ func TestBuildTLSArgs(t *testing.T) {
},
wantErr: false,
},
{
name: "central TLS config with curve preferences",
centralTLS: tlsProfile.TLSConfigProfile{
MinVersion: configv1.VersionTLS12,
CurvePreferences: []configv1.TLSGroup{
configv1.TLSGroupX25519MLKEM768,
configv1.TLSGroupX25519,
configv1.TLSGroupSecP256r1,
},
},
expected: []string{
"--tlsminversion",
"1.2",
"--tlscurvepreferences",
"X25519MLKEM768:X25519:CurveP256",
},
wantErr: false,
},
{
name: "omits curve preferences when all groups are unsupported",
centralTLS: tlsProfile.TLSConfigProfile{
MinVersion: configv1.VersionTLS12,
CurvePreferences: []configv1.TLSGroup{
configv1.TLSGroupSecP256r1MLKEM768,
},
},
expected: []string{
"--tlsminversion",
"1.2",
},
wantErr: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := BuildTLSArgsFromClusterTLSProfile(tt.centralTLS)
got, err := BuildTLSArgsFromClusterTLSProfile(tt.centralTLS, "test")
if tt.wantErr {
assert.Error(t, err)
assert.Nil(t, got)
return
}
assert.NoError(t, err)
if !reflect.DeepEqual(got, tt.expected) {
t.Fatalf("expected %#v got %#v", tt.expected, got)
}
Expand All @@ -3525,15 +3563,26 @@ func TestArgoCDServerAndRepoServerDeploymentArgs(t *testing.T) {
"ECDHE-RSA-AES128-GCM-SHA256",
"ECDHE-RSA-AES256-GCM-SHA384",
},
// Curve preferences are set on the central profile but omitted for
// server/repo-server until those components support --tlscurvepreferences.
CurvePreferences: []configv1.TLSGroup{
configv1.TLSGroupX25519,
configv1.TLSGroupSecP256r1,
},
}
deployment := &appsv1.Deployment{}
assert.NoError(t, r.reconcileServerDeployment(a, false))
assert.NoError(t, r.Get(context.TODO(), types.NamespacedName{Name: "argocd-server", Namespace: a.Namespace}, deployment))
args := []string{"--tlsminversion", "1.2", "--tlsciphers", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"}
args := []string{
"--tlsminversion", "1.2",
"--tlsciphers", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
}
assert.Equal(t, args, deployment.Spec.Template.Spec.Containers[0].Args)
assert.NotContains(t, deployment.Spec.Template.Spec.Containers[0].Args, "--tlscurvepreferences")
assert.NoError(t, r.reconcileRepoDeployment(a, false))
assert.NoError(t, r.Get(context.TODO(), types.NamespacedName{Name: "argocd-repo-server", Namespace: a.Namespace}, deployment))
assert.Equal(t, args, deployment.Spec.Template.Spec.Containers[0].Args)
assert.NotContains(t, deployment.Spec.Template.Spec.Containers[0].Args, "--tlscurvepreferences")
}

func TestReconcileServer_PromoterUIExtension(t *testing.T) {
Expand Down
5 changes: 4 additions & 1 deletion argocd-operator/controllers/argocd/image_updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,10 @@ func (r *ReconcileArgoCD) reconcileImageUpdaterDeployment(cr *argoproj.ArgoCD, s
}

args := []string{"run"}
imageUpdaterTLSProfileArguments := BuildTLSArgsFromClusterTLSProfile(r.CentralTLSConfigProfile)
imageUpdaterTLSProfileArguments, err := BuildTLSArgsFromClusterTLSProfile(r.CentralTLSConfigProfile, "argocd-image-updater")
if err != nil {
return err
Comment thread
akhilnittala marked this conversation as resolved.
}
args = append(args, imageUpdaterTLSProfileArguments...)

// Command is intentionally not set so that the image's own ENTRYPOINT applies.
Expand Down
86 changes: 82 additions & 4 deletions argocd-operator/controllers/argocd/image_updater_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1406,9 +1406,11 @@ func TestExpandImageUpdaterWatchNamespaces(t *testing.T) {

func TestReconcileImageUpdaterDeployment_TLSArgs(t *testing.T) {
tests := []struct {
name string
centralTLS tlsProfile.TLSConfigProfile
expectedArgs []string
name string
centralTLS tlsProfile.TLSConfigProfile
expectedArgs []string
unexpectedArgs []string
wantErr bool
}{
{
name: "central tls profile",
Expand All @@ -1427,12 +1429,51 @@ func TestReconcileImageUpdaterDeployment_TLSArgs(t *testing.T) {
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
},
},
{
name: "central tls profile with curve preferences",
centralTLS: tlsProfile.TLSConfigProfile{
DisableClusterTLSProfile: false,
MinVersion: configv1.VersionTLS12,
Ciphers: []string{
"ECDHE-RSA-AES128-GCM-SHA256",
},
CurvePreferences: []configv1.TLSGroup{
configv1.TLSGroupX25519MLKEM768,
configv1.TLSGroupX25519,
configv1.TLSGroupSecP256r1,
},
},
expectedArgs: []string{
"--tlsminversion",
"1.2",
"--tlsciphers",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"--tlscurvepreferences",
"X25519MLKEM768:X25519:CurveP256",
},
},
{
name: "Disable cluster tls profile",
centralTLS: tlsProfile.TLSConfigProfile{
DisableClusterTLSProfile: true,
},
expectedArgs: []string{},
expectedArgs: []string{},
unexpectedArgs: []string{"--tlsminversion", "--tlsciphers", "--tlscurvepreferences"},
},
{
name: "omits curve preferences when all groups are unsupported",
centralTLS: tlsProfile.TLSConfigProfile{
DisableClusterTLSProfile: false,
MinVersion: configv1.VersionTLS12,
CurvePreferences: []configv1.TLSGroup{
configv1.TLSGroupSecP256r1MLKEM768,
},
},
expectedArgs: []string{
"--tlsminversion",
"1.2",
},
unexpectedArgs: []string{"--tlscurvepreferences"},
},
}
for _, tt := range tests {
Expand All @@ -1452,6 +1493,10 @@ func TestReconcileImageUpdaterDeployment_TLSArgs(t *testing.T) {
CentralTLSConfigProfile: tt.centralTLS,
}
err := r.reconcileImageUpdaterDeployment(cr, sa, "", nil)
if tt.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
deployment := &appsv1.Deployment{}
err = client.Get(context.TODO(), types.NamespacedName{Name: nameWithSuffix(common.ArgoCDImageUpdaterControllerComponent, cr), Namespace: cr.Namespace}, deployment)
Expand All @@ -1460,10 +1505,43 @@ func TestReconcileImageUpdaterDeployment_TLSArgs(t *testing.T) {
for _, expected := range tt.expectedArgs {
assert.Contains(t, args, expected)
}
for _, unexpected := range tt.unexpectedArgs {
assert.NotContains(t, args, unexpected)
}
})
}
}

func TestReconcileImageUpdaterDeployment_DisabledWithUnsupportedCurves(t *testing.T) {
scheme := runtime.NewScheme()
_ = appsv1.AddToScheme(scheme)
_ = v1.AddToScheme(scheme)
_ = argoproj.AddToScheme(scheme)

cr := makeTestArgoCD()
cr.Spec.ImageUpdater.Enabled = false
sa := &v1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Name: "test-sa", Namespace: cr.Namespace}}
existing := newDeploymentWithSuffix(common.ArgoCDImageUpdaterControllerComponent, "controller", cr)
client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(cr, sa, existing).Build()
r := &ReconcileArgoCD{
Client: client,
Scheme: scheme,
CentralTLSConfigProfile: tlsProfile.TLSConfigProfile{
DisableClusterTLSProfile: false,
MinVersion: configv1.VersionTLS12,
CurvePreferences: []configv1.TLSGroup{
configv1.TLSGroupSecP256r1MLKEM768,
},
},
}

require.NoError(t, r.reconcileImageUpdaterDeployment(cr, sa, "", nil))

deployment := &appsv1.Deployment{}
err := client.Get(context.TODO(), types.NamespacedName{Name: existing.Name, Namespace: cr.Namespace}, deployment)
assert.True(t, errors.IsNotFound(err), "disabled Image Updater deployment should be deleted even when curve preferences are unsupported")
}

func TestSelectImageUpdaterImage(t *testing.T) {
tests := []struct {
name string
Expand Down
9 changes: 8 additions & 1 deletion argocd-operator/controllers/argocd/repo_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,14 @@ func (r *ReconcileArgoCD) reconcileRepoDeployment(cr *argocdoperatorv1beta1.Argo
repoServerVolumeMounts = append(repoServerVolumeMounts, cr.Spec.Repo.VolumeMounts...)
}

arguments := BuildTLSArgsFromClusterTLSProfile(r.CentralTLSConfigProfile)
// argocd-repo-server does not support --tlscurvepreferences yet; omit curves until a
// supporting image is the default. Keep min version and ciphers.
tlsProfileForRepoServer := r.CentralTLSConfigProfile
tlsProfileForRepoServer.CurvePreferences = nil
arguments, err := BuildTLSArgsFromClusterTLSProfile(tlsProfileForRepoServer, "argocd-repo-server")
if err != nil {
return err
}
deploy.Spec.Template.Spec.Containers = []corev1.Container{{
Args: arguments,
Command: getArgoRepoCommand(cr, useTLSForRedis),
Expand Down
Loading