Skip to content

Commit de4bbbe

Browse files
aledbfnandajavarma
andauthored
Add a new trust bundle for custom SSL certificates (#18450)
* Add a new trust bundle for custom SSL certificates * Mount the customer certificate in the workspace * Use the custom certificate in components * Cleanup * Set env variables and mount the crt in a different file * rename custom ca cert file name * Fix the filename in env vars * Enable custom SSL certificate conditionally --------- Co-authored-by: nandajavarma <[email protected]>
1 parent ba39001 commit de4bbbe

File tree

4 files changed

+92
-19
lines changed

4 files changed

+92
-19
lines changed

components/ws-manager-api/go/config/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ type Configuration struct {
133133
TimeoutMaxConcurrentReconciles int `json:"timeoutMaxConcurrentReconciles,omitempty"`
134134
// ExperimentalMode controls if experimental features are enabled
135135
ExperimentalMode bool `json:"experimentalMode"`
136+
// EnableCustomSSLCertificate controls if we need to support custom SSL certificates for git operations
137+
EnableCustomSSLCertificate bool `json:"enableCustomSSLCertificate"`
136138
}
137139

138140
type WorkspaceClass struct {

components/ws-manager-mk2/controllers/create.go

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,17 @@ func createDefiniteWorkspacePod(sctx *startWorkspaceContext) (*corev1.Pod, error
317317
},
318318
}
319319

320+
if sctx.Config.EnableCustomSSLCertificate {
321+
volumes = append(volumes, corev1.Volume{
322+
Name: "gitpod-ca-crt",
323+
VolumeSource: corev1.VolumeSource{
324+
ConfigMap: &corev1.ConfigMapVolumeSource{
325+
LocalObjectReference: corev1.LocalObjectReference{Name: "gitpod-customer-certificate-bundle"},
326+
},
327+
},
328+
})
329+
}
330+
320331
workloadType := "regular"
321332
if sctx.Headless {
322333
workloadType = "headless"
@@ -463,6 +474,29 @@ func createWorkspaceContainer(sctx *startWorkspaceContext) (*corev1.Container, e
463474

464475
image := fmt.Sprintf("%s/%s/%s", sctx.Config.RegistryFacadeHost, regapi.ProviderPrefixRemote, sctx.Workspace.Name)
465476

477+
volumeMounts := []corev1.VolumeMount{
478+
{
479+
Name: workspaceVolumeName,
480+
MountPath: workspaceDir,
481+
ReadOnly: false,
482+
MountPropagation: &mountPropagation,
483+
},
484+
{
485+
MountPath: "/.workspace",
486+
Name: "daemon-mount",
487+
MountPropagation: &mountPropagation,
488+
},
489+
}
490+
491+
if sctx.Config.EnableCustomSSLCertificate {
492+
volumeMounts = append(volumeMounts, corev1.VolumeMount{
493+
Name: "gitpod-ca-crt",
494+
MountPath: "/etc/ssl/certs/gitpod-ca.crt",
495+
SubPath: "ca-certificates.crt",
496+
ReadOnly: true,
497+
})
498+
}
499+
466500
return &corev1.Container{
467501
Name: "workspace",
468502
Image: image,
@@ -475,19 +509,7 @@ func createWorkspaceContainer(sctx *startWorkspaceContext) (*corev1.Container, e
475509
Limits: limits,
476510
Requests: requests,
477511
},
478-
VolumeMounts: []corev1.VolumeMount{
479-
{
480-
Name: workspaceVolumeName,
481-
MountPath: workspaceDir,
482-
ReadOnly: false,
483-
MountPropagation: &mountPropagation,
484-
},
485-
{
486-
MountPath: "/.workspace",
487-
Name: "daemon-mount",
488-
MountPropagation: &mountPropagation,
489-
},
490-
},
512+
VolumeMounts: volumeMounts,
491513
ReadinessProbe: readinessProbe,
492514
Env: env,
493515
Command: command,
@@ -547,10 +569,21 @@ func createWorkspaceEnvironment(sctx *startWorkspaceContext) ([]corev1.EnvVar, e
547569
result = append(result, corev1.EnvVar{Name: "THEIA_WEBVIEW_EXTERNAL_ENDPOINT", Value: "webview-{{hostname}}"})
548570
result = append(result, corev1.EnvVar{Name: "THEIA_MINI_BROWSER_HOST_PATTERN", Value: "browser-{{hostname}}"})
549571

550-
// We don't require that Git be configured for workspaces
551-
if sctx.Workspace.Spec.Git != nil {
552-
result = append(result, corev1.EnvVar{Name: "GITPOD_GIT_USER_NAME", Value: sctx.Workspace.Spec.Git.Username})
553-
result = append(result, corev1.EnvVar{Name: "GITPOD_GIT_USER_EMAIL", Value: sctx.Workspace.Spec.Git.Email})
572+
if sctx.Config.EnableCustomSSLCertificate {
573+
const (
574+
customCAMountPath = "/etc/ssl/certs/gitpod-ca.crt"
575+
certsMountPath = "/etc/ssl/certs/"
576+
)
577+
578+
result = append(result, corev1.EnvVar{Name: "NODE_EXTRA_CA_CERTS", Value: customCAMountPath})
579+
result = append(result, corev1.EnvVar{Name: "GIT_SSL_CAPATH", Value: certsMountPath})
580+
result = append(result, corev1.EnvVar{Name: "GIT_SSL_CAINFO", Value: customCAMountPath})
581+
582+
// We don't require that Git be configured for workspaces
583+
if sctx.Workspace.Spec.Git != nil {
584+
result = append(result, corev1.EnvVar{Name: "GITPOD_GIT_USER_NAME", Value: sctx.Workspace.Spec.Git.Username})
585+
result = append(result, corev1.EnvVar{Name: "GITPOD_GIT_USER_EMAIL", Value: sctx.Workspace.Spec.Git.Email})
586+
}
554587
}
555588

556589
// System level env vars

install/installer/pkg/components/cluster/certmanager.go

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,26 @@ func certmanager(ctx *common.RenderContext) ([]runtime.Object, error) {
3535
},
3636
}
3737

38+
gitpodCustomCertificateBundleSource := []trust.BundleSource{
39+
{
40+
UseDefaultCAs: pointer.Bool(false),
41+
},
42+
}
43+
3844
if ctx.Config.CustomCACert != nil {
3945
gitpodCaBundleSources = append(gitpodCaBundleSources, trust.BundleSource{
4046
Secret: &trust.SourceObjectKeySelector{
4147
Name: ctx.Config.CustomCACert.Name,
4248
KeySelector: trust.KeySelector{Key: "ca.crt"},
4349
},
4450
})
51+
52+
gitpodCustomCertificateBundleSource = append(gitpodCustomCertificateBundleSource, trust.BundleSource{
53+
Secret: &trust.SourceObjectKeySelector{
54+
Name: ctx.Config.CustomCACert.Name,
55+
KeySelector: trust.KeySelector{Key: "ca.crt"},
56+
},
57+
})
4558
}
4659

4760
// TODO (gpl): This is a workaround to untangle the refactoring of existing infrastructure from
@@ -54,7 +67,7 @@ func certmanager(ctx *common.RenderContext) ([]runtime.Object, error) {
5467
return nil
5568
})
5669

57-
return []runtime.Object{
70+
objects := []runtime.Object{
5871
// Define a self-signed issuer so we can generate a CA
5972
&v1.ClusterIssuer{
6073
TypeMeta: common.TypeMetaCertificateClusterIssuer,
@@ -180,5 +193,26 @@ func certmanager(ctx *common.RenderContext) ([]runtime.Object, error) {
180193
},
181194
},
182195
},
183-
}, nil
196+
}
197+
198+
if ctx.Config.CustomCACert != nil {
199+
objects = append(objects,
200+
// trust Bundle for custom SSL certificates
201+
&trust.Bundle{
202+
TypeMeta: common.TypeMetaBundle,
203+
ObjectMeta: metav1.ObjectMeta{
204+
Name: "gitpod-customer-certificate-bundle",
205+
},
206+
Spec: trust.BundleSpec{
207+
Sources: gitpodCustomCertificateBundleSource,
208+
Target: trust.BundleTarget{
209+
ConfigMap: &trust.KeySelector{
210+
Key: "ca-certificates.crt",
211+
},
212+
},
213+
},
214+
})
215+
}
216+
217+
return objects, nil
184218
}

install/installer/pkg/components/ws-manager-mk2/configmap.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,10 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
262262
}{Addr: fmt.Sprintf(":%d", HealthPort)},
263263
}
264264

265+
if ctx.Config.CustomCACert != nil {
266+
wsmcfg.Manager.EnableCustomSSLCertificate = true
267+
}
268+
265269
fc, err := common.ToJSONString(wsmcfg)
266270
if err != nil {
267271
return nil, fmt.Errorf("failed to marshal ws-manager config: %w", err)

0 commit comments

Comments
 (0)