Skip to content

Commit

Permalink
feat: add self-signed certificate init container (#141)
Browse files Browse the repository at this point in the history
* Add self signed init container enabled with selfSignedCert in values.

* reorder comment

* #133

* #136

* minor improvements

* use sslip

* fix: probes with enabled tls

* bump zitadel version

* use sslip

* use sslip

* test selfSigned.enabled

* bump chart testing action

* only probe on http

* increase timeout

---------

Co-authored-by: PurseChicken <[email protected]>
  • Loading branch information
eliobischof and PurseChicken authored Nov 13, 2023
1 parent 1d174f3 commit 4e17d23
Show file tree
Hide file tree
Showing 28 changed files with 298 additions and 85 deletions.
58 changes: 45 additions & 13 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ jobs:

- id: 'set-up-chart-testing'
name: Install Chart Testing CLI
uses: 'helm/chart-testing-action@v2.4.0'
uses: 'helm/chart-testing-action@v2.6.1'
with:
version: 'v3.8.0'

Expand Down Expand Up @@ -95,34 +95,66 @@ jobs:

- id: 'test'
name: Run Go Tests
run: 'go test ./...'
run: 'go test -p 1 ./...'
if: steps.list-changed.outputs.changed == 'true'

- id: 'zitadel-test-namespaces'
name: Grep Created Namespaces
run: |
echo "inlineSecretsNamespace=$(kubectl get namespaces --output name | grep 1-inline-secrets | cut -d / -f 2)" >> "$GITHUB_OUTPUT"
echo "refSecretsNamespace=$(kubectl get namespaces --output name | grep 2-ref-secrets | cut -d / -f 2)" >> "$GITHUB_OUTPUT"
echo "machineKeyNamespace=$(kubectl get namespaces --output name | grep 3-machine-key | cut -d / -f 2)" >> "$GITHUB_OUTPUT"
echo "pgInsecure=$(kubectl get namespaces --output name | grep 1-postgres-insecure | cut -d / -f 2)" >> "$GITHUB_OUTPUT"
echo "pgSecure=$(kubectl get namespaces --output name | grep 2-postgres-secure | cut -d / -f 2)" >> "$GITHUB_OUTPUT"
echo "crInsecure=$(kubectl get namespaces --output name | grep 3-cockroach-insecure | cut -d / -f 2)" >> "$GITHUB_OUTPUT"
echo "crSecure=$(kubectl get namespaces --output name | grep 4-cockroach-secure | cut -d / -f 2)" >> "$GITHUB_OUTPUT"
echo "refSecrets=$(kubectl get namespaces --output name | grep 5-referenced-secrets | cut -d / -f 2)" >> "$GITHUB_OUTPUT"
echo "machineUser=$(kubectl get namespaces --output name | grep 6-machine-user | cut -d / -f 2)" >> "$GITHUB_OUTPUT"
echo "selfSigned=$(kubectl get namespaces --output name | grep 7-self-signed | cut -d / -f 2)" >> "$GITHUB_OUTPUT"
if: always()

- id: 'namespace-report-inline-secrets'
name: Show Inline Secrets Namespace
- id: 'namespace-report-pg-insecure'
name: Show ${{ steps.zitadel-test-namespaces.outputs.pgInsecure }} Namespace
uses: jupyterhub/action-k8s-namespace-report@v1
if: always()
with:
namespace: ${{ steps.zitadel-test-namespaces.outputs.inlineSecretsNamespace }}
namespace: ${{ steps.zitadel-test-namespaces.outputs.pgInsecure }}

- id: 'namespace-report-pg-secure'
name: Show ${{ steps.zitadel-test-namespaces.outputs.pgSecure }} Namespace
uses: jupyterhub/action-k8s-namespace-report@v1
if: always()
with:
namespace: ${{ steps.zitadel-test-namespaces.outputs.pgSecure }}

- id: 'namespace-report-cr-insecure'
name: Show ${{ steps.zitadel-test-namespaces.outputs.crInsecure }} Namespace
uses: jupyterhub/action-k8s-namespace-report@v1
if: always()
with:
namespace: ${{ steps.zitadel-test-namespaces.outputs.crInsecure }}

- id: 'namespace-report-cr-secure'
name: Show ${{ steps.zitadel-test-namespaces.outputs.crSecure }} Namespace
uses: jupyterhub/action-k8s-namespace-report@v1
if: always()
with:
namespace: ${{ steps.zitadel-test-namespaces.outputs.crSecure }}

- id: 'namespace-report-ref-secrets'
name: Show Referenced Secrets Namespace
name: Show ${{ steps.zitadel-test-namespaces.outputs.refSecrets }} Namespace
uses: jupyterhub/action-k8s-namespace-report@v1
if: always()
with:
namespace: ${{ steps.zitadel-test-namespaces.outputs.refSecrets }}

- id: 'namespace-report-machine-user'
name: Show ${{ steps.zitadel-test-namespaces.outputs.machineUser }} Namespace
uses: jupyterhub/action-k8s-namespace-report@v1
if: always()
with:
namespace: ${{ steps.zitadel-test-namespaces.outputs.refSecretsNamespace }}
namespace: ${{ steps.zitadel-test-namespaces.outputs.machineUser }}

- id: 'namespace-report-machine-key'
name: Show Machine Key Namespace
- id: 'namespace-report-self-signed'
name: Show ${{ steps.zitadel-test-namespaces.outputs.selfSigned }} Namespace
uses: jupyterhub/action-k8s-namespace-report@v1
if: always()
with:
namespace: ${{ steps.zitadel-test-namespaces.outputs.machineKeyNamespace }}
namespace: ${{ steps.zitadel-test-namespaces.outputs.selfSigned }}
4 changes: 2 additions & 2 deletions charts/zitadel/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ apiVersion: v2
name: zitadel
description: A Helm chart for ZITADEL
type: application
appVersion: "v2.35.0"
version: 7.1.0
appVersion: "v2.41.0"
version: 7.2.0
kubeVersion: ">= 1.21.0-0"
icon: https://zitadel.com/zitadel-logo-dark.svg
maintainers:
Expand Down
77 changes: 57 additions & 20 deletions charts/zitadel/acceptance/acceptance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@ import (
func TestPostgresInsecure(t *testing.T) {
t.Parallel()
example := "1-postgres-insecure"
workDir, values := workingDirectory(example)
workDir, valuesFile, values := readConfig(t, example)
cfg := values.Zitadel.ConfigmapConfig
suite.Run(t, acceptance.Configure(
t,
newNamespaceIdentifier(example),
acceptance.Postgres.WithValues(filepath.Join(workDir, "postgres-values.yaml")),
[]string{values},
"",
[]string{valuesFile},
cfg.ExternalDomain,
cfg.ExternalPort,
cfg.ExternalSecure,
nil,
nil,
nil,
Expand All @@ -30,13 +33,16 @@ func TestPostgresInsecure(t *testing.T) {
func TestPostgresSecure(t *testing.T) {
t.Parallel()
example := "2-postgres-secure"
workDir, values := workingDirectory(example)
workDir, valuesFile, values := readConfig(t, example)
cfg := values.Zitadel.ConfigmapConfig
suite.Run(t, acceptance.Configure(
t,
newNamespaceIdentifier(example),
acceptance.Postgres.WithValues(filepath.Join(workDir, "postgres-values.yaml")),
[]string{values},
"",
[]string{valuesFile},
cfg.ExternalDomain,
cfg.ExternalPort,
cfg.ExternalSecure,
func(cfg *acceptance.ConfigurationTest) {
k8s.KubectlApply(t, cfg.KubeOptions, filepath.Join(workDir, "certs-job.yaml"))
k8s.WaitUntilJobSucceed(t, cfg.KubeOptions, "create-certs", 120, 3*time.Second)
Expand All @@ -49,13 +55,16 @@ func TestPostgresSecure(t *testing.T) {
func TestCockroachInsecure(t *testing.T) {
t.Parallel()
example := "3-cockroach-insecure"
workDir, values := workingDirectory(example)
workDir, valuesFile, values := readConfig(t, example)
cfg := values.Zitadel.ConfigmapConfig
suite.Run(t, acceptance.Configure(
t,
newNamespaceIdentifier(example),
acceptance.Cockroach.WithValues(filepath.Join(workDir, "cockroach-values.yaml")),
[]string{values},
"",
[]string{valuesFile},
cfg.ExternalDomain,
cfg.ExternalPort,
cfg.ExternalSecure,
nil,
nil,
nil,
Expand All @@ -65,13 +74,16 @@ func TestCockroachInsecure(t *testing.T) {
func TestCockroachSecure(t *testing.T) {
t.Parallel()
example := "4-cockroach-secure"
workDir, values := workingDirectory(example)
workDir, valuesFile, values := readConfig(t, example)
cfg := values.Zitadel.ConfigmapConfig
suite.Run(t, acceptance.Configure(
t,
newNamespaceIdentifier(example),
acceptance.Cockroach.WithValues(filepath.Join(workDir, "cockroach-values.yaml")),
[]string{values},
"",
[]string{valuesFile},
cfg.ExternalDomain,
cfg.ExternalPort,
cfg.ExternalSecure,
nil,
func(cfg *acceptance.ConfigurationTest) {
k8s.KubectlApply(t, cfg.KubeOptions, filepath.Join(workDir, "zitadel-cert-job.yaml"))
Expand All @@ -84,13 +96,16 @@ func TestCockroachSecure(t *testing.T) {
func TestReferencedSecrets(t *testing.T) {
t.Parallel()
example := "5-referenced-secrets"
workDir, values := workingDirectory(example)
workDir, valuesFile, values := readConfig(t, example)
cfg := values.Zitadel.ConfigmapConfig
suite.Run(t, acceptance.Configure(
t,
newNamespaceIdentifier(example),
acceptance.Postgres.WithValues(filepath.Join(workDir, "postgres-values.yaml")),
[]string{values},
"",
[]string{valuesFile},
cfg.ExternalDomain,
cfg.ExternalPort,
cfg.ExternalSecure,
nil,
func(cfg *acceptance.ConfigurationTest) {
k8s.KubectlApply(t, cfg.KubeOptions, filepath.Join(workDir, "zitadel-secrets.yaml"))
Expand All @@ -103,16 +118,38 @@ func TestReferencedSecrets(t *testing.T) {
func TestMachineUser(t *testing.T) {
t.Parallel()
example := "6-machine-user"
workDir, values := workingDirectory(example)
saUserame := readValues(t, values).Zitadel.ConfigmapConfig.FirstInstance.Org.Machine.Machine.Username
workDir, valuesFile, values := readConfig(t, example)
cfg := values.Zitadel.ConfigmapConfig
saUsername := cfg.FirstInstance.Org.Machine.Machine.Username
suite.Run(t, acceptance.Configure(
t,
newNamespaceIdentifier(example),
acceptance.Postgres.WithValues(filepath.Join(workDir, "postgres-values.yaml")),
[]string{values},
"",
[]string{valuesFile},
cfg.ExternalDomain,
cfg.ExternalPort,
cfg.ExternalSecure,
nil,
nil,
testAuthenticatedAPI(saUserame, fmt.Sprintf("%s.json", saUserame))),
testAuthenticatedAPI(saUsername, fmt.Sprintf("%s.json", saUsername))),
)
}

func TestSelfSigned(t *testing.T) {
t.Parallel()
example := "7-self-signed"
workDir, valuesFile, values := readConfig(t, example)
cfg := values.Zitadel.ConfigmapConfig
suite.Run(t, acceptance.Configure(
t,
newNamespaceIdentifier(example),
acceptance.Postgres.WithValues(filepath.Join(workDir, "postgres-values.yaml")),
[]string{valuesFile},
cfg.ExternalDomain,
cfg.ExternalPort,
cfg.ExternalSecure,
nil,
nil,
nil,
))
}
17 changes: 13 additions & 4 deletions charts/zitadel/acceptance/accessibility.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ package acceptance

import (
"context"
"crypto/x509"
"errors"
"fmt"
mgmt_api "github.com/zitadel/zitadel-go/v2/pkg/client/zitadel/management"
"net/http"
"strconv"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -75,6 +78,10 @@ func (s *ConfigurationTest) checkAccessibility(pods []corev1.Pod) {
checkOptionsFunc(func(ctx context.Context) error {
randomInvalidKey := `{"type":"serviceaccount","keyId":"229185755715993707","key":"-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAm8bpVfzWJuZsEz1VfTrwSAdkbH+i/u2NS4dv60lwIjtXzrU7\n1xZkHw9jxqz+c+APTaTzp1KY49Dc/wcwXv032FuD1GK2ZSRnMaHm8QnNt8Xhi0e8\nBlu3QQmlqxWPCI67wDPUwXoSHM+r9gQXn2pOR0oonoLP+Gzef+RRj1zUFpZmHWPX\nxw4UWWHwl4xChw9iyO4HbZZGe6wBVYVWe2BnvviCVEeKapyjaCqokZES38S4+S2X\nit202xLlRDyXs3XFWmBzHGmEsxx3LZZor85Kbph/bGjDcV8rdQC1YKC++z8OhuLp\n79GltP7YWrfMN3Z8iRUJQY9APrKQYtljVkWrnQIDAQABAoIBAQCIRZrLyRHCF+LF\ndes6UPvv1t+n9oQtRLxNLV7f0m+Q0p7+yhZeE01kyn67R4yU65YXk0w+vIfZC1a4\nlp5fCl73Gx+ZBP2QPyczCPHRPIVE1Yt33zoByevmrjzKDGMC1nIyMmVVF6eOorFI\n1s2ffEycGqir+b1bEkoWUTJ0Gn3Cf1PE4vTgenHhCrYSvMsbmszQ5GDlfxNj27qf\nF2YrnLx11GplMYU0YEzGqSQHxw76rrmF7yiTvbB+olsjXWARAJxBriSlrF2BDYQk\n+HJ8MEwhWhncaZH1i0Xz/jarDBizpo2o1+K1ZqF6RBUknT72EPnMxI9JsvS4FH44\nZfbrujBhAoGBAMQnx6tO79GpnBIAr7iELyUu5F4mCdU6D0rOAiCjXPpCUAdCDuwX\nzROonIGXPPmhzXXtxebeTz4cf+P8p6tUnrqpl/f0Oi1DMOzv0jL/SAUDC9uUrg6k\nurXZT2dgeONwd1pADyNXSpbZfwRE5IoecFg6cgFi4kune0mdG3mr8QjpAoGBAMtN\nerrMc+4bc3GsmWG4FSXn3xlWMeVGIo2/owP2P5MuMu0ibjofZkl28y0xo8dJgWmv\nLiFSEOhUy+TXZK7K1a2+fD+AXHHaHkBjNbTmCaAbf7rZnuUL4iZVpQyIoTCVuAwo\nC6bsE4TcwGddk4yZj/WZ7v1be+uNgeYwQr2UshyVAoGAN8pYsBCzhR6IlVY8pG50\nOk8sBNss0MjCsLQHRuEwAL37pRTUybG7UmwSl4k8foPWvEP0lcWFJFVWyrGBvulC\nfDTgVFXSdi02LS3Iy1hwU3yaUsnm96NCt5YnT2/Q8l96kuDFbXfWbzFNPxmZJu+h\nZHa7FknZs0rfdgCJYAHXfIECgYEAw3kSqSrNyMICJOkkbO2W/+RLAUx8GwttS8dX\nkQaip/wCoTi6rQ3lxnslY23YIFRPpvL1srn6YbiudrCXMOz7uNtvEYt01082SQha\n6j1IQfZOwLRfb7EWV29/i2aPPWynEqEqWuuf9N5f7MLvjH9WCHpibJ4aryhXHqGG\nekvPWWUCgYA5qDsPk5ykRWEALbunzB/RkpxR6LTLSwriU/OzRswOiKo8UPqH4JZI\nOsFAgudG5H+UOEGMuaSvIq0PLbGex16PjKqUsRwgIoPdH8183f9fxZSJDmr7ELIy\nZJEvE3eJnYwMOpSEZS0VR5Sw0CmKV2Hhd+u6rRB8YjXMP0nAVg8eOA==\n-----END RSA PRIVATE KEY-----\n","userId":"229185755715600491"}`
conn, err := OpenGRPCConnection(s, []byte(randomInvalidKey))
if errors.As(err, &x509.UnknownAuthorityError{}) {
// The gRPC client doesn't support skipping the server cert validation
return nil
}
if err != nil {
return fmt.Errorf("couldn't create gRPC management client: %w", err)
}
Expand All @@ -87,12 +94,14 @@ func (s *ConfigurationTest) checkAccessibility(pods []corev1.Pod) {
}))
for i := range pods {
pod := pods[i]
port := 8081 + i

podTunnel := k8s.NewTunnel(s.KubeOptions, k8s.ResourceTypePod, pod.Name, port, 8080)
podTunnel := k8s.NewTunnel(s.KubeOptions, k8s.ResourceTypePod, pod.Name, 0, 8080)
podTunnel.ForwardPort(s.T())
tunnels = append(tunnels, podTunnel)
checks = append(checks, zitadelStatusChecks(s.Scheme, s.Domain, uint16(port))...)
localPort, err := strconv.ParseUint(strings.Split(podTunnel.Endpoint(), ":")[1], 10, 16)
if err != nil {
s.T().Fatal(err)
}
checks = append(checks, zitadelStatusChecks(s.Scheme, s.Domain, uint16(localPort))...)
}
wg := sync.WaitGroup{}
for _, check := range checks {
Expand Down
1 change: 1 addition & 0 deletions charts/zitadel/acceptance/await.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func Await(ctx context.Context, t *testing.T, wg *sync.WaitGroup, tries int, cb
if tries == 0 {
t.Fatal(err)
}
t.Logf("got error %v. trying again in a second", err)
time.Sleep(time.Second)
Await(ctx, t, wg, tries-1, cb)
}
14 changes: 8 additions & 6 deletions charts/zitadel/acceptance/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ func Configure(
dbChart databaseChart,
zitadelValues []string,
externalDomain string,
externalPort uint16,
externalSecure bool,
before, afterDB, afterZITADEL hookFunc,
) *ConfigurationTest {
chartPath, err := filepath.Abs("..")
Expand All @@ -77,9 +79,9 @@ func Configure(
if err != nil {
t.Fatal(err)
}
domain := "localhost"
if externalDomain != "" {
domain = externalDomain
externalScheme := "http"
if externalSecure {
externalScheme = "https"
}
cfg := &ConfigurationTest{
Ctx: context.Background(),
Expand All @@ -95,9 +97,9 @@ func Configure(
beforeFunc: before,
afterDBFunc: afterDB,
afterZITADELFunc: afterZITADEL,
Domain: domain,
Port: 8080,
Scheme: "http",
Domain: externalDomain,
Port: externalPort,
Scheme: externalScheme,
}
cfg.SetT(t)
return cfg
Expand Down
20 changes: 17 additions & 3 deletions charts/zitadel/acceptance/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@ import (
"testing"
)

func readValues(t *testing.T, valuesFilePath string) (values struct {
type Values struct {
Zitadel struct {
MasterkeySecretName string `yaml:"masterkeySecretName"`
ConfigSecretName string `yaml:"configSecretName"`
ConfigmapConfig struct {
FirstInstance struct {
ExternalDomain string `yaml:"ExternalDomain"`
ExternalPort uint16 `yaml:"ExternalPort"`
ExternalSecure bool `yaml:"ExternalSecure"`
FirstInstance struct {
Org struct {
Machine struct {
Machine struct {
Expand All @@ -27,7 +30,13 @@ func readValues(t *testing.T, valuesFilePath string) (values struct {
} `yaml:"FirstInstance"`
} `yaml:"configmapConfig"`
} `yaml:"zitadel"`
}) {
}

func readValues(t *testing.T, valuesFilePath string) (values Values) {
// set default values like in the defaults.yaml
values.Zitadel.ConfigmapConfig.ExternalDomain = "localhost"
values.Zitadel.ConfigmapConfig.ExternalPort = 8080
values.Zitadel.ConfigmapConfig.ExternalSecure = true
valuesBytes, err := os.ReadFile(valuesFilePath)
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -65,3 +74,8 @@ func workingDirectory(exampleDir string) (workingDir, valuesFile string) {
valuesFile = filepath.Join(workingDir, "zitadel-values.yaml")
return workingDir, valuesFile
}

func readConfig(t *testing.T, exampleDir string) (string, string, Values) {
workingDir, valuesFile := workingDirectory(exampleDir)
return workingDir, valuesFile, readValues(t, valuesFile)
}
4 changes: 3 additions & 1 deletion charts/zitadel/acceptance/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package acceptance

import (
"context"
"crypto/tls"
"fmt"
"io"
"net/http"
Expand All @@ -23,7 +24,8 @@ func httpCall(ctx context.Context, method string, url string, beforeSend func(re
if beforeSend != nil {
beforeSend(req)
}
resp, err := http.DefaultClient.Do(req)
httpClient := http.Client{Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}}
resp, err := httpClient.Do(req)
if err != nil {
return nil, nil, fmt.Errorf("sending request %+v failed: %s", *req, err)
}
Expand Down
Loading

0 comments on commit 4e17d23

Please sign in to comment.