Skip to content
Merged
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
50 changes: 46 additions & 4 deletions templates/_common.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,27 @@ storageClassName: {{ $storageClass | default "" | quote }}
value: {{ .Values.postgres.sslMode | quote }}
- name: DB_NAME
value: {{ .Values.postgres.database | quote }}
{{- if ne .Values.postgres.ssl.certSecret.name "" }}
- name: DB_CERT
value: "/etc/ssl/certs/pg/cert/{{ .Values.postgres.ssl.certSecret.key }}"
{{- end }}
{{- if ne .Values.postgres.ssl.keySecret.name "" }}
- name: DB_KEY
value: "/etc/ssl/certs/pg/key/{{ .Values.postgres.ssl.keySecret.key }}"
{{- end }}
{{- if ne .Values.postgres.ssl.rootCertSecret.name "" }}
- name: DB_ROOT_CERT
value: "/etc/ssl/certs/pg/rootcert/{{ .Values.postgres.ssl.rootCertSecret.key }}"
{{- end }}
{{- end }}
{{- end }}
{{/*
coder.volumes adds a volumes stanza if a cert.secret is provided.
*/}}
{{- define "coder.volumes" }}
{{- if or (merge .Values dict | dig "certs" "secret" "name" false) (ne (include "movedValue" (dict "Values" .Values "Key" "coderd.tls.hostSecretName")) "") }}
volumes:
{{- end }}
- name: tmp-pgcerts
emptyDir: {}
{{- if (merge .Values dict | dig "certs" "secret" "name" false) }}
- name: {{ .Values.certs.secret.name | quote }}
secret:
Expand All @@ -64,15 +76,30 @@ volumes:
secret:
secretName: {{ include "movedValue" (dict "Values" .Values "Key" "coderd.tls.devurlsHostSecretName") }}
{{- end }}
{{- if ne .Values.postgres.ssl.certSecret.name "" }}
- name: pgcert
secret:
secretName: {{ .Values.postgres.ssl.certSecret.name | quote }}
{{- end }}
{{- if ne .Values.postgres.ssl.keySecret.name "" }}
- name: pgkey
secret:
secretName: {{ .Values.postgres.ssl.keySecret.name | quote }}
{{- end }}
{{- if ne .Values.postgres.ssl.rootCertSecret.name "" }}
- name: pgrootcert
secret:
secretName: {{ .Values.postgres.ssl.rootCertSecret.name | quote }}
{{- end }}
{{- end }}

{{/*
coder.volumeMounts adds a volume mounts stanza if a cert.secret is provided.
*/}}
{{- define "coder.volumeMounts" }}
{{- if or (merge .Values dict | dig "certs" "secret" "name" false) (ne (include "movedValue" (dict "Values" .Values "Key" "coderd.tls.hostSecretName")) "") }}
volumeMounts:
{{- end }}
- name: tmp-pgcerts
mountPath: /tmp/pgcerts
{{- if (merge .Values dict | dig "certs" "secret" "name" false) }}
- name: {{ .Values.certs.secret.name | quote }}
mountPath: /etc/ssl/certs/{{ .Values.certs.secret.key }}
Expand All @@ -88,6 +115,21 @@ volumeMounts:
mountPath: /etc/ssl/certs/devurls
readOnly: true
{{- end }}
{{- if ne .Values.postgres.ssl.certSecret.name "" }}
- name: pgcert
mountPath: /etc/ssl/certs/pg/cert
readOnly: true
{{- end }}
{{- if ne .Values.postgres.ssl.keySecret.name "" }}
- name: pgkey
mountPath: /etc/ssl/certs/pg/key
readOnly: true
{{- end }}
{{- if ne .Values.postgres.ssl.rootCertSecret.name "" }}
- name: pgrootcert
mountPath: /etc/ssl/certs/pg/rootcert
readOnly: true
{{- end }}
{{- end }}
{{/*
coder.serviceTolerations adds tolerations if any are specified to
Expand Down
1 change: 1 addition & 0 deletions templates/coderd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ spec:
{{- else }}
{{- toYaml .Values.coderd.securityContext | nindent 12 }}
{{- end }}
{{- include "coder.volumeMounts" . | indent 10 }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How did this work before?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It didn't need volume mounts before.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

huh, I would've thought we'd need volume mounts for TLS certs and stuff 🤷‍♂️

{{- end }}
containers:
- name: {{ include "coder.serviceName" . }}
Expand Down
97 changes: 44 additions & 53 deletions tests/examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ package tests
import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/chartutil"
"helm.sh/helm/v3/pkg/engine"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/utils/pointer"
)
Expand All @@ -17,50 +16,24 @@ import (
func TestExamples(t *testing.T) {
t.Parallel()

chart, err := loader.LoadDir("..")
require.NoError(t, err, "loaded chart successfully")
require.NotNil(t, chart, "chart must be non-nil")
chart := LoadChart(t)

exampleOpenShift, err := ReadValuesAsMap("../examples/openshift/openshift.values.yaml")
exampleOpenShift, err := ReadValuesFileAsMap("../examples/openshift/openshift.values.yaml")
require.NoError(t, err, "failed to load OpenShift example values")

exampleKind, err := ReadValuesAsMap("../examples/kind/kind.values.yaml")
exampleKind, err := ReadValuesFileAsMap("../examples/kind/kind.values.yaml")
require.NoError(t, err, "failed to load Kind example values")

tests := []struct {
Name string
Values map[string]interface{}
PodSecurityContext *corev1.PodSecurityContext
ContainerSecurityContext *corev1.SecurityContext
Postgres *PostgresValues
}{
{
Name: "default",
Values: nil,
PodSecurityContext: &corev1.PodSecurityContext{
RunAsUser: pointer.Int64(1000),
RunAsGroup: nil,
RunAsNonRoot: pointer.Bool(true),
SeccompProfile: &corev1.SeccompProfile{
Type: corev1.SeccompProfileTypeRuntimeDefault,
LocalhostProfile: nil,
},
},
ContainerSecurityContext: &corev1.SecurityContext{
RunAsUser: nil,
RunAsGroup: nil,
RunAsNonRoot: nil,
Capabilities: nil,
Privileged: nil,
SELinuxOptions: nil,
WindowsOptions: nil,
ReadOnlyRootFilesystem: pointer.Bool(true),
AllowPrivilegeEscalation: pointer.Bool(false),
ProcMount: nil,
SeccompProfile: &corev1.SeccompProfile{
Type: corev1.SeccompProfileTypeRuntimeDefault,
LocalhostProfile: nil,
},
},
}, {
Name: "openshift",
Values: exampleOpenShift,
Expand Down Expand Up @@ -113,40 +86,58 @@ func TestExamples(t *testing.T) {
},
}

var (
defaultPsp = &corev1.PodSecurityContext{
RunAsUser: pointer.Int64(1000),
RunAsNonRoot: pointer.Bool(true),
SeccompProfile: &corev1.SeccompProfile{
Type: corev1.SeccompProfileTypeRuntimeDefault,
},
}

defaultCsc = &corev1.SecurityContext{
ReadOnlyRootFilesystem: pointer.Bool(true),
AllowPrivilegeEscalation: pointer.Bool(false),
SeccompProfile: &corev1.SeccompProfile{
Type: corev1.SeccompProfileTypeRuntimeDefault,
},
}
)

for _, test := range tests {
test := test

if test.PodSecurityContext == nil {
test.PodSecurityContext = defaultPsp
}
if test.ContainerSecurityContext == nil {
test.ContainerSecurityContext = defaultCsc
}

t.Run(test.Name, func(t *testing.T) {
t.Parallel()

values, err := chartutil.ToRenderValues(chart, test.Values, DefaultReleaseOptions(), chartutil.DefaultCapabilities.Copy())
values, err := chartutil.ToRenderValues(chart.chart, test.Values, DefaultReleaseOptions(), chartutil.DefaultCapabilities.Copy())
require.NoError(t, err, "failed to generate render values")

manifests, err := engine.Render(chart, values)
manifests, err := engine.Render(chart.chart, values)
require.NoError(t, err, "failed to render chart")

objs, err := LoadObjectsFromManifests(manifests)
require.NoError(t, err, "failed to convert manifests to objects")

// Find the coderd Deployment
var found bool
for _, obj := range objs {
deployment, ok := obj.(*appsv1.Deployment)
if ok && deployment.Name == "coderd" {
found = true

require.Equal(t, test.PodSecurityContext,
deployment.Spec.Template.Spec.SecurityContext,
"expected matching pod securityContext")
require.Len(t, deployment.Spec.Template.Spec.Containers, 1,
"expected one container")
require.Equal(t, test.ContainerSecurityContext,
deployment.Spec.Template.Spec.Containers[0].SecurityContext,
"expected matching container securityContext")

break
}
}
require.True(t, found, "expected coderd deployment in manifests")
coderd := MustFindDeployment(t, objs, "coderd")

assert.Equal(t, test.PodSecurityContext, coderd.Spec.Template.Spec.SecurityContext,
"expected matching pod securityContext",
)
require.Len(t, coderd.Spec.Template.Spec.Containers, 1,
"expected one container",
)
assert.Equal(t, test.ContainerSecurityContext, coderd.Spec.Template.Spec.Containers[0].SecurityContext,
"expected matching container securityContext",
)
})
}
}
68 changes: 68 additions & 0 deletions tests/pgssl_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package tests

import (
"path"
"strings"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
"k8s.io/utils/pointer"
)

func TestPgSSL(t *testing.T) {
t.Parallel()

var (
secretName = pointer.String("pg-certs")
pgval = &PostgresValues{
Default: &PostgresDefaultValues{Enable: pointer.Bool(false)},
Host: pointer.String("1.1.1.1"),
Port: pointer.String("5432"),
User: pointer.String("postgres"),
Database: pointer.String("postgres"),
PasswordSecret: pointer.String("pg-pass"),
SSLMode: pointer.String("require"),
SSL: &PostgresSSLValues{
CertSecret: &CertsSecretValues{
Name: secretName,
Key: pointer.String("cert"),
},
KeySecret: &CertsSecretValues{
Name: secretName,
Key: pointer.String("key"),
},
RootCertSecret: &CertsSecretValues{
Name: secretName,
Key: pointer.String("rootcert"),
},
},
}

objs = LoadChart(t).MustRender(t, func(cv *CoderValues) { cv.Postgres = pgval })
coderd = MustFindDeployment(t, objs, "coderd")
)

for _, vol := range []string{"pgcert", "pgkey", "pgrootcert"} {
AssertVolume(t, coderd.Spec.Template.Spec.Volumes, vol, func(t testing.TB, v corev1.Volume) {
require.NotNilf(t, v.Secret, "secret nil for %q", vol)
assert.Equalf(t, "pg-certs", v.Secret.SecretName, "secret name incorrect for %q", vol)
})
}

for _, cnt := range []string{"migrations", "coderd"} {
// Combine both init and regular containers.
cnts := append(coderd.Spec.Template.Spec.InitContainers, coderd.Spec.Template.Spec.Containers...)

AssertContainer(t, cnts, cnt, func(t testing.TB, c corev1.Container) {
for _, vol := range []string{"pgcert", "pgkey", "pgrootcert"} {
AssertVolumeMount(t, c.VolumeMounts, vol, func(t testing.TB, v corev1.VolumeMount) {
assert.Equalf(t, vol, v.Name, "volume mount name incorrect for %q", vol)
assert.Truef(t, v.ReadOnly, "readonly incorrect for %q", vol)
assert.Equalf(t, path.Join("/etc/ssl/certs/pg/", strings.TrimPrefix(v.Name, "pg")), v.MountPath, "mount path incorrect for %q", vol)
})
}
})
}
}
Loading