Skip to content

Commit f1c338a

Browse files
authored
Merge branch 'argoproj-labs:master' into master
2 parents 1311c6e + 1b1e16e commit f1c338a

10 files changed

Lines changed: 379 additions & 22 deletions

File tree

OWNERS

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
1-
owners:
2-
- jomkz
1+
# https://www.kubernetes.dev/docs/guide/owners/
32

43
approvers:
5-
- iam-veeramalla
6-
- wtam2018
4+
- anandf
5+
- anandrkskd
6+
- chetan-rns
77
- jannfis
8-
- jopit
8+
- jgwest
9+
- olivergondza
10+
- svghadi
11+
- wtam2018
912

1013
reviewers:
14+
- jparsai
15+
- Rizwana777
16+
17+
emeritus_approvers:
18+
- ciiay
1119
- iam-veeramalla
12-
- wtam2018
13-
- jannfis
14-
- jopit
15-
- jaideepr97
16-
- ishitasequeira
20+
- ishitasequeira
21+
- jomkz
1722
- reginapizza
18-
- ciiay
19-
- svghadi
2023
- saumeya
21-

controllers/argocd/argocd_controller.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import (
3737

3838
errs "errors"
3939

40+
configv1 "github.com/openshift/api/config/v1"
4041
rbacv1 "k8s.io/api/rbac/v1"
4142
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
4243
ctrl "sigs.k8s.io/controller-runtime"
@@ -102,10 +103,20 @@ type ReconcileArgoCD struct {
102103
// re-run to renew the Dex OAuth client token before it expires.
103104
// Key: ArgoCD namespace, Value: time.Duration
104105
dexTokenRequeueAfter sync.Map
106+
// CentralTLSConfigProfile specifies the TLS configuration profile in the cluster.
107+
CentralTLSConfigProfile TLSConfigProfile
105108
}
106109

107110
var log = logr.Log.WithName("controller_argocd")
108111

112+
type TLSConfigProfile struct {
113+
DisableClusterTLSProfile bool
114+
// MinVersion specifies the minimum TLS version configured in cluster.
115+
MinVersion configv1.TLSProtocolVersion
116+
// Ciphers specifies the list of supported TLS cipher suites in cluster.
117+
Ciphers []string
118+
}
119+
109120
// Map to keep track of running Argo CD instances using their namespaces as key and phase as value
110121
// This map will be used for the performance metrics purposes
111122
// Important note: This assumes that each instance only contains one Argo CD instance

controllers/argocd/deployment.go

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,22 +220,54 @@ func getArgoImportVolumes(cr *argoprojv1alpha1.ArgoCDExport) []corev1.Volume {
220220
return volumes
221221
}
222222

223-
func getArgoRedisArgs(useTLS bool) []string {
223+
func getArgoRedisArgs(useTLS bool, centralTLSConfig TLSConfigProfile) []string {
224224
args := make([]string, 0)
225225

226226
args = append(args, "--save", "")
227227
args = append(args, "--appendonly", "no")
228228
args = append(args, "--aclfile", argoutil.RedisAuthMountPath+"users.acl")
229229

230230
if useTLS {
231+
if !centralTLSConfig.DisableClusterTLSProfile {
232+
arguments := BuildRedisArgsFromClusterTLSProfile(centralTLSConfig)
233+
args = append(args, arguments...)
234+
}
231235
args = append(args, "--tls-port", "6379")
232236
args = append(args, "--port", "0")
233237

234238
args = append(args, "--tls-cert-file", "/app/config/redis/tls/tls.crt")
235239
args = append(args, "--tls-key-file", "/app/config/redis/tls/tls.key")
236240
args = append(args, "--tls-auth-clients", "no")
237241
}
242+
return args
243+
}
238244

245+
// BuildRedisArgsFromClusterTLSProfile builds arguments for redis deployment based on central tls config.
246+
func BuildRedisArgsFromClusterTLSProfile(centralTLSConfig TLSConfigProfile) []string {
247+
var (
248+
args []string
249+
protocol string
250+
ciphers []string
251+
)
252+
if v := argoutil.RedisTLSProtocolVersionString(centralTLSConfig.MinVersion); v != "" {
253+
protocol = v
254+
args = append(args, "--tls-protocols", protocol)
255+
}
256+
ciphers = argoutil.MapCipherSuites(centralTLSConfig.Ciphers)
257+
// Build cipher args
258+
if len(ciphers) > 0 {
259+
cipherString := strings.Join(ciphers, ":")
260+
if protocol == "TLSv1.3" {
261+
// TLS 1.3 only
262+
args = append(args, "--tls-ciphersuites", cipherString)
263+
} else {
264+
// TLS 1.2 or mixed TLS 1.2/1.3
265+
args = append(args,
266+
"--tls-ciphers", cipherString,
267+
"--tls-ciphersuites", cipherString,
268+
)
269+
}
270+
}
239271
return args
240272
}
241273

@@ -440,9 +472,9 @@ func (r *ReconcileArgoCD) reconcileRedisDeployment(cr *argoproj.ArgoCD, useTLS b
440472
RunAsUser: int64Ptr(1000),
441473
}
442474
}
443-
475+
arguments := getArgoRedisArgs(useTLS, r.CentralTLSConfigProfile)
444476
deploy.Spec.Template.Spec.Containers = []corev1.Container{{
445-
Args: getArgoRedisArgs(useTLS),
477+
Args: arguments,
446478
Image: argoutil.GetRedisContainerImage(cr),
447479
ImagePullPolicy: argoutil.GetImagePullPolicy(cr.Spec.ImagePullPolicy),
448480
Name: "redis",

controllers/argocd/deployment_test.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import (
2626
"github.com/google/go-cmp/cmp"
2727
"github.com/stretchr/testify/assert"
2828

29+
configv1 "github.com/openshift/api/config/v1"
30+
2931
argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1"
3032
)
3133

@@ -3134,3 +3136,104 @@ func TestReconcileArgoCD_reconcileRedisDeployment_customLabelsAndAnnotations(t *
31343136
assert.False(t, hasCustomAnnotation)
31353137
assert.False(t, hasCustomLabel)
31363138
}
3139+
3140+
func TestBuildRedisArgs(t *testing.T) {
3141+
tests := []struct {
3142+
name string
3143+
centralTLS TLSConfigProfile
3144+
expected []string
3145+
wantErr bool
3146+
}{
3147+
{
3148+
name: "central TLS config with invalid min version",
3149+
centralTLS: TLSConfigProfile{
3150+
MinVersion: configv1.TLSProtocolVersion("INVALID"),
3151+
},
3152+
expected: nil,
3153+
wantErr: false,
3154+
},
3155+
{
3156+
name: "central TLS config with tls 1.2",
3157+
centralTLS: TLSConfigProfile{
3158+
MinVersion: configv1.VersionTLS12,
3159+
Ciphers: []string{
3160+
"ECDHE-RSA-AES128-GCM-SHA256",
3161+
},
3162+
},
3163+
expected: []string{
3164+
"--tls-protocols",
3165+
"TLSv1.2",
3166+
"--tls-ciphers",
3167+
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
3168+
"--tls-ciphersuites",
3169+
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
3170+
},
3171+
wantErr: false,
3172+
},
3173+
{
3174+
name: "central TLS config with tls 1.3",
3175+
centralTLS: TLSConfigProfile{
3176+
MinVersion: configv1.VersionTLS13,
3177+
Ciphers: []string{
3178+
"TLS_AES_128_GCM_SHA256",
3179+
},
3180+
},
3181+
expected: []string{
3182+
"--tls-protocols",
3183+
"TLSv1.3",
3184+
"--tls-ciphersuites",
3185+
"TLS_AES_128_GCM_SHA256",
3186+
},
3187+
wantErr: false,
3188+
},
3189+
{
3190+
name: "central TLS config only version",
3191+
centralTLS: TLSConfigProfile{
3192+
MinVersion: configv1.VersionTLS12,
3193+
},
3194+
expected: []string{
3195+
"--tls-protocols",
3196+
"TLSv1.2",
3197+
},
3198+
wantErr: false,
3199+
},
3200+
{
3201+
name: "central TLS config only ciphers",
3202+
centralTLS: TLSConfigProfile{
3203+
Ciphers: []string{
3204+
"ECDHE-RSA-AES256-GCM-SHA384",
3205+
},
3206+
},
3207+
expected: []string{
3208+
"--tls-ciphers",
3209+
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
3210+
"--tls-ciphersuites",
3211+
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
3212+
},
3213+
wantErr: false,
3214+
},
3215+
{
3216+
name: "central TLS config with unmapped cipher",
3217+
centralTLS: TLSConfigProfile{
3218+
MinVersion: configv1.VersionTLS12,
3219+
Ciphers: []string{
3220+
"INVALID",
3221+
},
3222+
},
3223+
expected: []string{
3224+
"--tls-protocols",
3225+
"TLSv1.2",
3226+
},
3227+
wantErr: false,
3228+
},
3229+
}
3230+
3231+
for _, tt := range tests {
3232+
t.Run(tt.name, func(t *testing.T) {
3233+
got := BuildRedisArgsFromClusterTLSProfile(tt.centralTLS)
3234+
if !reflect.DeepEqual(got, tt.expected) {
3235+
t.Fatalf("expected %#v got %#v", tt.expected, got)
3236+
}
3237+
})
3238+
}
3239+
}

controllers/argocdagent/deployment.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,21 @@ func updateDeploymentIfChanged(compName, saName string, cr *argoproj.ArgoCD, dep
289289
deployment.Spec.Template.Spec.Containers[0].Args = buildArgs(compName)
290290
}
291291

292+
redisAuthVolume, redisAuthMount := argoutil.MountRedisAuthToArgo(cr)
293+
desiredVolumeMounts := append(buildVolumeMounts(), redisAuthMount)
294+
desiredVolumes := append(buildVolumes(), redisAuthVolume)
295+
if !reflect.DeepEqual(deployment.Spec.Template.Spec.Containers[0].VolumeMounts, desiredVolumeMounts) {
296+
log.Info("deployment container volume mounts are being updated")
297+
changed = true
298+
deployment.Spec.Template.Spec.Containers[0].VolumeMounts = desiredVolumeMounts
299+
}
300+
301+
if !reflect.DeepEqual(deployment.Spec.Template.Spec.Volumes, desiredVolumes) {
302+
log.Info("deployment container volumes are being updated")
303+
changed = true
304+
deployment.Spec.Template.Spec.Volumes = desiredVolumes
305+
}
306+
292307
if !reflect.DeepEqual(deployment.Spec.Template.Spec.Containers[0].SecurityContext, buildSecurityContext()) {
293308
log.Info("deployment container security context is being updated")
294309
changed = true

controllers/argoutil/tls.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ import (
2828

2929
certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
3030

31+
configv1 "github.com/openshift/api/config/v1"
32+
3133
"github.com/argoproj-labs/argocd-operator/common"
3234
)
3335

@@ -122,3 +124,56 @@ func NewSignedCertificate(cfg *certmanagerv1.CertificateSpec, dnsNames []string,
122124
}
123125
return x509.ParseCertificate(certDERBytes)
124126
}
127+
128+
// -------------------- Redis TLS Args --------------------
129+
130+
func TLSProtocolVersionString(v configv1.TLSProtocolVersion) string {
131+
switch v {
132+
case configv1.VersionTLS10:
133+
return "1.0"
134+
case configv1.VersionTLS11:
135+
return "1.1"
136+
case configv1.VersionTLS12:
137+
return "1.2"
138+
case configv1.VersionTLS13:
139+
return "1.3"
140+
default:
141+
return ""
142+
}
143+
}
144+
145+
func RedisTLSProtocolVersionString(v configv1.TLSProtocolVersion) string {
146+
version := TLSProtocolVersionString(v)
147+
if version == "" {
148+
return ""
149+
}
150+
if version == "1.0" {
151+
return "TLSv1"
152+
}
153+
return "TLSv" + version
154+
}
155+
156+
func MapCipherSuites(names []string) []string {
157+
m := map[string]string{
158+
"TLS_AES_128_GCM_SHA256": "TLS_AES_128_GCM_SHA256", // 0x13,0x01
159+
"TLS_AES_256_GCM_SHA384": "TLS_AES_256_GCM_SHA384", // 0x13,0x02
160+
"TLS_CHACHA20_POLY1305_SHA256": "TLS_CHACHA20_POLY1305_SHA256", // 0x13,0x03
161+
"ECDHE-ECDSA-AES128-GCM-SHA256": "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", // 0xC0,0x2B
162+
"ECDHE-RSA-AES128-GCM-SHA256": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", // 0xC0,0x2F
163+
"ECDHE-ECDSA-AES256-GCM-SHA384": "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", // 0xC0,0x2C
164+
"ECDHE-RSA-AES256-GCM-SHA384": "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", // 0xC0,0x30
165+
"ECDHE-ECDSA-CHACHA20-POLY1305": "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", // 0xCC,0xA9
166+
"ECDHE-RSA-CHACHA20-POLY1305": "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", // 0xCC,0xA8
167+
// Go's crypto/tls does not support CBC mode and DHE ciphers, so we don't want to include them here.
168+
// See:
169+
// - https://github.com/golang/go/issues/26652
170+
// - https://github.com/golang/go/issues/7758
171+
}
172+
out := make([]string, 0, len(names))
173+
for _, name := range names {
174+
if mapped, ok := m[name]; ok {
175+
out = append(out, mapped)
176+
}
177+
}
178+
return out
179+
}

0 commit comments

Comments
 (0)