Skip to content

Commit

Permalink
revert acceptance
Browse files Browse the repository at this point in the history
  • Loading branch information
eliobischof committed Oct 4, 2024
1 parent aa1c630 commit fd76753
Show file tree
Hide file tree
Showing 16 changed files with 890 additions and 0 deletions.
155 changes: 155 additions & 0 deletions charts/zitadel/acceptance/acceptance_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package acceptance_test

import (
"fmt"
"path/filepath"
"testing"
"time"

"github.com/gruntwork-io/terratest/modules/k8s"
"github.com/stretchr/testify/suite"
"github.com/zitadel/zitadel-charts/charts/zitadel/acceptance"
)

func TestPostgresInsecure(t *testing.T) {
t.Parallel()
example := "1-postgres-insecure"
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,
))
}

func TestPostgresSecure(t *testing.T) {
t.Parallel()
example := "2-postgres-secure"
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,
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)
},
nil,
nil,
))
}

func TestCockroachInsecure(t *testing.T) {
t.Parallel()
example := "3-cockroach-insecure"
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{valuesFile},
cfg.ExternalDomain,
cfg.ExternalPort,
cfg.ExternalSecure,
nil,
nil,
nil,
))
}

func TestCockroachSecure(t *testing.T) {
t.Parallel()
example := "4-cockroach-secure"
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{valuesFile},
cfg.ExternalDomain,
cfg.ExternalPort,
cfg.ExternalSecure,
nil,
func(cfg *acceptance.ConfigurationTest) {
k8s.KubectlApply(t, cfg.KubeOptions, filepath.Join(workDir, "zitadel-cert-job.yaml"))
k8s.WaitUntilJobSucceed(t, cfg.KubeOptions, "create-zitadel-cert", 120, 3*time.Second)
},
nil,
))
}

func TestReferencedSecrets(t *testing.T) {
t.Parallel()
example := "5-referenced-secrets"
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,
func(cfg *acceptance.ConfigurationTest) {
k8s.KubectlApply(t, cfg.KubeOptions, filepath.Join(workDir, "zitadel-secrets.yaml"))
k8s.KubectlApply(t, cfg.KubeOptions, filepath.Join(workDir, "zitadel-masterkey.yaml"))
},
nil,
))
}

func TestMachineUser(t *testing.T) {
t.Parallel()
example := "6-machine-user"
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{valuesFile},
cfg.ExternalDomain,
cfg.ExternalPort,
cfg.ExternalSecure,
nil,
nil,
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,
))
}
138 changes: 138 additions & 0 deletions charts/zitadel/acceptance/accessibility.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package acceptance

import (
"context"
"crypto/x509"
"errors"
"fmt"
"net/http"
"strconv"
"strings"
"sync"
"time"

mgmt_api "github.com/zitadel/zitadel-go/v2/pkg/client/zitadel/management"

"github.com/gruntwork-io/terratest/modules/k8s"
corev1 "k8s.io/api/core/v1"
)

type checkOptions interface {
execute(ctx context.Context) error
}

type checkOptionsFunc func(ctx context.Context) error

func (f checkOptionsFunc) execute(ctx context.Context) error {
return f(ctx)
}

type httpCheckOptions struct {
getUrl string
test func(response *http.Response, body []byte) error
}

func (c *httpCheckOptions) execute(ctx context.Context) (err error) {
checkCtx, checkCancel := context.WithTimeout(ctx, 5*time.Second)
defer checkCancel()
//nolint:bodyclose
resp, body, err := HttpGet(checkCtx, c.getUrl, nil)
if err != nil {
return fmt.Errorf("HttpGet failed with response %+v and body %+v: %w", resp, body, err)
}
if err = c.test(resp, body); err != nil {
return fmt.Errorf("checking response %+v with body %+v failed: %w", resp, body, err)
}
return nil
}

func (s *ConfigurationTest) checkAccessibility(pods []corev1.Pod) {
ctx, cancel := context.WithTimeout(s.Ctx, time.Minute)
defer cancel()
apiBaseURL := s.APIBaseURL()
tunnels := []interface{ Close() }{CloseFunc(ServiceTunnel(s))}
defer func() {
for _, t := range tunnels {
t.Close()
}
}()
checks := append(
zitadelStatusChecks(s.Scheme, s.Domain, s.Port),
&httpCheckOptions{
getUrl: apiBaseURL + "/ui/console/assets/environment.json",
test: func(resp *http.Response, body []byte) error {
if err := checkHttpStatus200(resp, body); err != nil {
return err
}
bodyStr := string(body)
for _, expect := range []string{
fmt.Sprintf(`"api":"%s"`, apiBaseURL),
fmt.Sprintf(`"issuer":"%s"`, apiBaseURL),
} {
if !strings.Contains(bodyStr, expect) {
return fmt.Errorf("couldn't find %s in environment.json content %s", expect, bodyStr)
}
}
return nil
},
},
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)
}
_, err = conn.Healthz(ctx, &mgmt_api.HealthzRequest{})
// TODO: Why is the key checked on the healthz RPC?
if strings.Contains(err.Error(), "Errors.AuthNKey.NotFound") ||
strings.Contains(err.Error(), "Errors.User.NotFound") ||
strings.Contains(err.Error(), "assertion invalid") {
err = nil
}
return err
}))
for i := range pods {
pod := pods[i]
podTunnel := k8s.NewTunnel(s.KubeOptions, k8s.ResourceTypePod, pod.Name, 0, 8080)
podTunnel.ForwardPort(s.T())
tunnels = append(tunnels, podTunnel)
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 {
wg.Add(1)
go Await(ctx, s.T(), &wg, 60, check.execute)
}
wait(ctx, s.T(), &wg, "accessibility")
}

func zitadelStatusChecks(scheme, domain string, port uint16) []checkOptions {
return []checkOptions{
&httpCheckOptions{
getUrl: fmt.Sprintf("%s://%s:%d/debug/validate", scheme, domain, port),
test: checkHttpStatus200,
},
&httpCheckOptions{
getUrl: fmt.Sprintf("%s://%s:%d/debug/healthz", scheme, domain, port),
test: checkHttpStatus200,
},
&httpCheckOptions{
getUrl: fmt.Sprintf("%s://%s:%d/debug/ready", scheme, domain, port),
test: checkHttpStatus200,
}}
}

func checkHttpStatus200(resp *http.Response, _ []byte) error {
if resp.StatusCode != 200 {
return fmt.Errorf("expected status code 200 but got %d", resp.StatusCode)
}
return nil
}
8 changes: 8 additions & 0 deletions charts/zitadel/acceptance/after.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package acceptance

func (s *ConfigurationTest) AfterTest(_, _ string) {
if s.afterZITADELFunc == nil || s.T().Failed() {
return
}
s.afterZITADELFunc(s)
}
Loading

0 comments on commit fd76753

Please sign in to comment.