From bdbc2623e84ba0eb25f2106548aff68031b754a6 Mon Sep 17 00:00:00 2001 From: Joao Marcal Date: Tue, 31 Mar 2026 11:24:26 +0100 Subject: [PATCH 1/2] e2e: isolate Docker networks for parallel integration tests Use a per-test network name derived from t.Name() with e2e.WithName, since bare e2e.New() hashes runtime.Caller(3) and collides on testing.tRunner for every test. Derive TLS/OIDC hostnames from e.Name() via getContainerName, drop fixed env name constants, and align Dex/tenant API host with the observatorium-api runnable. --- test/e2e/alerts_test.go | 6 ++-- test/e2e/configs.go | 11 ------- test/e2e/helpers.go | 51 +++++++++++------------------ test/e2e/interactive_test.go | 6 ++-- test/e2e/logs_test.go | 6 ++-- test/e2e/metrics_test.go | 6 ++-- test/e2e/openapi_test.go | 6 ++-- test/e2e/probes_test.go | 24 +++++++------- test/e2e/redis_rate_limiter_test.go | 2 +- test/e2e/rules_test.go | 6 ++-- test/e2e/services.go | 6 ++-- test/e2e/tenants_test.go | 6 ++-- test/e2e/traces_test.go | 18 +++++----- 13 files changed, 66 insertions(+), 88 deletions(-) diff --git a/test/e2e/alerts_test.go b/test/e2e/alerts_test.go index 078749052..cb0d9f64e 100644 --- a/test/e2e/alerts_test.go +++ b/test/e2e/alerts_test.go @@ -24,12 +24,12 @@ import ( func TestAlertmanagerApiProxy(t *testing.T) { t.Parallel() - e, err := e2e.New(e2e.WithName(envAlertmanagerName)) + e, err := e2e.New(e2e.WithName(uniqueE2ENetworkName(t))) testutil.Ok(t, err) t.Cleanup(e.Close) - prepareConfigsAndCerts(t, alerts, e) - _, token, rateLimiterAddr := startBaseServices(t, e, alerts) + prepareConfigsAndCerts(t, e) + _, token, rateLimiterAddr := startBaseServices(t, e) alertmanagerEndpoint := newAlertmanagerService(e) readEndpoint, writeEndpoint, _ := startServicesForMetrics(t, e) testutil.Ok(t, e2e.StartAndWaitReady(alertmanagerEndpoint)) diff --git a/test/e2e/configs.go b/test/e2e/configs.go index 67a4fdbb5..b119e2f7b 100644 --- a/test/e2e/configs.go +++ b/test/e2e/configs.go @@ -31,17 +31,6 @@ const ( certsSharedDir = "certs" configSharedDir = "config" - envMetricsName = "metrics" - envRulesAPIName = "rules-api" - envAlertmanagerName = "alertmanager-api" - envLogsName = "logs-tail" - envTracesName = "traces-export" - envTracesTempoName = "traces-tempo" - envTracesTemplateName = "traces-template" - envTenantsName = "tenants" - envInteractive = "interactive" - envProbesName = "probes" - defaultTenantID = "1610b0c3-c509-4592-a256-a1871353dbfa" mtlsTenantID = "845cdfd9-f936-443c-979c-2ee7dc91f646" diff --git a/test/e2e/helpers.go b/test/e2e/helpers.go index a678b69a4..d7be79b35 100644 --- a/test/e2e/helpers.go +++ b/test/e2e/helpers.go @@ -3,6 +3,7 @@ package e2e import ( + "crypto/sha256" "crypto/tls" "crypto/x509" "encoding/json" @@ -21,16 +22,26 @@ import ( "github.com/observatorium/api/test/testtls" ) +// uniqueE2ENetworkName returns a Docker-valid e2e network name (≤16 chars, [-a-zA-Z0-9]) +// that is distinct for each Go test. efficientgo/e2e's default name hashes runtime.Caller(3), +// which resolves to testing.tRunner for every test, so bare e2e.New() would assign the same +// network to all parallel tests and reproduce Docker network races. +func uniqueE2ENetworkName(t *testing.T) string { + t.Helper() + sum := sha256.Sum256([]byte(t.Name())) + return fmt.Sprintf("%x", sum[:8]) // 16 hex digits +} + // Generates certificates and copies static configuration to the shared directory. -func prepareConfigsAndCerts(t *testing.T, tt testType, e e2e.Environment) { +func prepareConfigsAndCerts(t *testing.T, e e2e.Environment) { testutil.Ok( t, testtls.GenerateCerts( filepath.Join(e.SharedDir(), certsSharedDir), - getContainerName(t, tt, "observatorium-api"), - []string{getContainerName(t, tt, "observatorium-api"), "127.0.0.1"}, - getContainerName(t, tt, "dex"), - []string{getContainerName(t, tt, "dex"), "127.0.0.1"}, + getContainerName(e, "observatorium-api"), + []string{getContainerName(e, "observatorium-api"), "127.0.0.1"}, + getContainerName(e, "dex"), + []string{getContainerName(e, "dex"), "127.0.0.1"}, ), ) @@ -82,32 +93,10 @@ func obtainToken(endpoint string, tlsConf *tls.Config) (string, error) { return t.IDToken, nil } -func getContainerName(t *testing.T, tt testType, serviceName string) string { - switch tt { - case logs: - return envLogsName + "-" + serviceName - case metrics: - return envMetricsName + "-" + serviceName - case rules: - return envRulesAPIName + "-" + serviceName - case alerts: - return envAlertmanagerName + "-" + serviceName - case tenants: - return envTenantsName + "-" + serviceName - case interactive: - return envInteractive + "-" + serviceName - case probes: - return envProbesName + "-" + serviceName - case traces: - return envTracesName + "-" + serviceName - case tracesTemplate: - return envTracesTemplateName + "-" + serviceName - case tracesTempo: - return envTracesTempoName + "-" + serviceName - default: - t.Fatal("invalid test type provided") - return "" - } +// getContainerName returns the Docker DNS hostname for a service in this environment. +// It must match e2e's naming ({networkName}-{runnableName}) so TLS SANs and OIDC redirects stay correct. +func getContainerName(e e2e.Environment, serviceName string) string { + return e.Name() + "-" + serviceName } func getTLSClientConfig(t *testing.T, e e2e.Environment) *tls.Config { diff --git a/test/e2e/interactive_test.go b/test/e2e/interactive_test.go index be8795a25..ee28778dc 100644 --- a/test/e2e/interactive_test.go +++ b/test/e2e/interactive_test.go @@ -14,12 +14,12 @@ import ( func TestInteractiveSetup(t *testing.T) { fmt.Printf("Starting services...\n") - e, err := e2e.New(e2e.WithName(envInteractive)) + e, err := e2e.New(e2e.WithName(uniqueE2ENetworkName(t))) testutil.Ok(t, err) t.Cleanup(e.Close) - prepareConfigsAndCerts(t, interactive, e) - _, token, rateLimiterAddr := startBaseServices(t, e, interactive) + prepareConfigsAndCerts(t, e) + _, token, rateLimiterAddr := startBaseServices(t, e) readEndpoint, writeEndpoint, readExtEndpoint := startServicesForMetrics(t, e) logsEndpoint, logsExtEndpoint := startServicesForLogs(t, e) rulesEndpoint := startServicesForRules(t, e) diff --git a/test/e2e/logs_test.go b/test/e2e/logs_test.go index 1b3654228..5ebb50bee 100644 --- a/test/e2e/logs_test.go +++ b/test/e2e/logs_test.go @@ -18,12 +18,12 @@ import ( func TestLogs(t *testing.T) { t.Parallel() - e, err := e2e.New(e2e.WithName(envLogsName)) + e, err := e2e.New(e2e.WithName(uniqueE2ENetworkName(t))) testutil.Ok(t, err) t.Cleanup(e.Close) - prepareConfigsAndCerts(t, logs, e) - _, token, rateLimiterAddr := startBaseServices(t, e, logs) + prepareConfigsAndCerts(t, e) + _, token, rateLimiterAddr := startBaseServices(t, e) logsEndpoint, logsExtEndpoint := startServicesForLogs(t, e) api, err := newObservatoriumAPIService( diff --git a/test/e2e/metrics_test.go b/test/e2e/metrics_test.go index 3e42bbe66..8bc46518f 100644 --- a/test/e2e/metrics_test.go +++ b/test/e2e/metrics_test.go @@ -24,12 +24,12 @@ import ( func TestMetricsReadAndWrite(t *testing.T) { t.Parallel() - e, err := e2e.New(e2e.WithName(envMetricsName)) + e, err := e2e.New(e2e.WithName(uniqueE2ENetworkName(t))) testutil.Ok(t, err) t.Cleanup(e.Close) - prepareConfigsAndCerts(t, metrics, e) - _, token, rateLimiterAddr := startBaseServices(t, e, metrics) + prepareConfigsAndCerts(t, e) + _, token, rateLimiterAddr := startBaseServices(t, e) readEndpoint, writeEndpoint, readExtEndpoint := startServicesForMetrics(t, e) api, err := newObservatoriumAPIService( diff --git a/test/e2e/openapi_test.go b/test/e2e/openapi_test.go index 6c41b70f6..7dc7de4bf 100644 --- a/test/e2e/openapi_test.go +++ b/test/e2e/openapi_test.go @@ -15,12 +15,12 @@ import ( func TestOpenAPIEndpoint(t *testing.T) { t.Parallel() - e, err := e2e.New(e2e.WithName(envMetricsName)) + e, err := e2e.New(e2e.WithName(uniqueE2ENetworkName(t))) testutil.Ok(t, err) t.Cleanup(e.Close) - prepareConfigsAndCerts(t, metrics, e) - _, _, _ = startBaseServices(t, e, metrics) + prepareConfigsAndCerts(t, e) + _, _, _ = startBaseServices(t, e) readEndpoint, writeEndpoint, _ := startServicesForMetrics(t, e) api, err := newObservatoriumAPIService( diff --git a/test/e2e/probes_test.go b/test/e2e/probes_test.go index bbbe32b9a..de4d568af 100644 --- a/test/e2e/probes_test.go +++ b/test/e2e/probes_test.go @@ -15,12 +15,12 @@ import ( ) func TestProbes_CreateAndGetProbe(t *testing.T) { - e, err := e2e.New(e2e.WithName(envProbesName)) + e, err := e2e.New(e2e.WithName(uniqueE2ENetworkName(t))) testutil.Ok(t, err) t.Cleanup(e.Close) - prepareConfigsAndCerts(t, probes, e) - _, token, rateLimiterAddr := startBaseServices(t, e, probes) + prepareConfigsAndCerts(t, e) + _, token, rateLimiterAddr := startBaseServices(t, e) probesEndpoint := startServicesForProbes(t, e) api, err := newObservatoriumAPIService( @@ -112,12 +112,12 @@ func TestProbes_CreateAndGetProbe(t *testing.T) { } func TestProbes_ListProbes(t *testing.T) { - e, err := e2e.New(e2e.WithName(envProbesName)) + e, err := e2e.New(e2e.WithName(uniqueE2ENetworkName(t))) testutil.Ok(t, err) t.Cleanup(e.Close) - prepareConfigsAndCerts(t, probes, e) - _, token, rateLimiterAddr := startBaseServices(t, e, probes) + prepareConfigsAndCerts(t, e) + _, token, rateLimiterAddr := startBaseServices(t, e) probesEndpoint := startServicesForProbes(t, e) api, err := newObservatoriumAPIService( @@ -218,12 +218,12 @@ func TestProbes_ListProbes(t *testing.T) { } func TestProbes_CreateProbeConflict(t *testing.T) { - e, err := e2e.New(e2e.WithName(envProbesName)) + e, err := e2e.New(e2e.WithName(uniqueE2ENetworkName(t))) testutil.Ok(t, err) t.Cleanup(e.Close) - prepareConfigsAndCerts(t, probes, e) - _, token, rateLimiterAddr := startBaseServices(t, e, probes) + prepareConfigsAndCerts(t, e) + _, token, rateLimiterAddr := startBaseServices(t, e) probesEndpoint := startServicesForProbes(t, e) api, err := newObservatoriumAPIService( @@ -282,12 +282,12 @@ func TestProbes_CreateProbeConflict(t *testing.T) { } func TestProbes_UnauthorizedAccess(t *testing.T) { - e, err := e2e.New(e2e.WithName(envProbesName)) + e, err := e2e.New(e2e.WithName(uniqueE2ENetworkName(t))) testutil.Ok(t, err) t.Cleanup(e.Close) - prepareConfigsAndCerts(t, probes, e) - _, _, rateLimiterAddr := startBaseServices(t, e, probes) + prepareConfigsAndCerts(t, e) + _, _, rateLimiterAddr := startBaseServices(t, e) probesEndpoint := startServicesForProbes(t, e) api, err := newObservatoriumAPIService( diff --git a/test/e2e/redis_rate_limiter_test.go b/test/e2e/redis_rate_limiter_test.go index 47e1597b2..42b249ed3 100644 --- a/test/e2e/redis_rate_limiter_test.go +++ b/test/e2e/redis_rate_limiter_test.go @@ -17,7 +17,7 @@ import ( func TestRedisRateLimiter_GetRateLimits(t *testing.T) { t.Parallel() // Start isolated environment with given ref. - e, err := e2e.New(e2e.WithName("redis-rate-li")) + e, err := e2e.New(e2e.WithName(uniqueE2ENetworkName(t))) testutil.Ok(t, err) t.Cleanup(e.Close) diff --git a/test/e2e/rules_test.go b/test/e2e/rules_test.go index c88a8f0ef..5ddabafd8 100644 --- a/test/e2e/rules_test.go +++ b/test/e2e/rules_test.go @@ -110,12 +110,12 @@ const metricsNilRulesYamlTpl = `` func TestRulesAPI(t *testing.T) { t.Parallel() - e, err := e2e.New(e2e.WithName(envRulesAPIName)) + e, err := e2e.New(e2e.WithName(uniqueE2ENetworkName(t))) testutil.Ok(t, err) t.Cleanup(e.Close) - prepareConfigsAndCerts(t, rules, e) - _, token, rateLimiterAddr := startBaseServices(t, e, rules) + prepareConfigsAndCerts(t, e) + _, token, rateLimiterAddr := startBaseServices(t, e) metricsRulesEndpoint := startServicesForRules(t, e) logsRulesEndpoint, _ := startServicesForLogs(t, e) diff --git a/test/e2e/services.go b/test/e2e/services.go index fb041608a..7652bf815 100644 --- a/test/e2e/services.go +++ b/test/e2e/services.go @@ -177,19 +177,19 @@ func startServicesForProbes(t *testing.T, e e2e.Environment) (probesEndpoint str } // startBaseServices starts and waits until all base services required for the test are ready. -func startBaseServices(t *testing.T, e e2e.Environment, tt testType) ( +func startBaseServices(t *testing.T, e e2e.Environment) ( dex *e2emon.InstrumentedRunnable, token string, rateLimiterAddr string, ) { - createDexYAML(t, e, getContainerName(t, tt, "dex"), getContainerName(t, tt, "observatorium_api")) + createDexYAML(t, e, getContainerName(e, "dex"), getContainerName(e, "observatorium-api")) dex = newDexService(e) gubernator := newGubernatorService(e) opa := newOPAService(e) testutil.Ok(t, e2e.StartAndWaitReady(dex, gubernator, opa)) - createTenantsYAML(t, e, dex.InternalEndpoint("https"), opa.InternalEndpoint("http"), getContainerName(t, tt, "observatorium_api")) + createTenantsYAML(t, e, dex.InternalEndpoint("https"), opa.InternalEndpoint("http"), getContainerName(e, "observatorium-api")) token, err := obtainToken(dex.Endpoint("https"), getTLSClientConfig(t, e)) testutil.Ok(t, err) diff --git a/test/e2e/tenants_test.go b/test/e2e/tenants_test.go index 271689b99..7bcd35fab 100644 --- a/test/e2e/tenants_test.go +++ b/test/e2e/tenants_test.go @@ -15,12 +15,12 @@ import ( func TestTenantsRetryAuthenticationProviderRegistration(t *testing.T) { t.Parallel() - e, err := e2e.New(e2e.WithName(envTenantsName)) + e, err := e2e.New(e2e.WithName(uniqueE2ENetworkName(t))) testutil.Ok(t, err) t.Cleanup(e.Close) - prepareConfigsAndCerts(t, tenants, e) - dex, _, _ := startBaseServices(t, e, tenants) + prepareConfigsAndCerts(t, e) + dex, _, _ := startBaseServices(t, e) readEndpoint, writeEndpoint, _ := startServicesForMetrics(t, e) // Start API with stopped Dex and observe retries. diff --git a/test/e2e/traces_test.go b/test/e2e/traces_test.go index e43d98263..78e78997e 100644 --- a/test/e2e/traces_test.go +++ b/test/e2e/traces_test.go @@ -146,12 +146,12 @@ const ( func TestTracesExport(t *testing.T) { t.Parallel() - e, err := e2e.New(e2e.WithName(envTracesName)) + e, err := e2e.New(e2e.WithName(uniqueE2ENetworkName(t))) testutil.Ok(t, err) t.Cleanup(e.Close) - prepareConfigsAndCerts(t, traces, e) - _, token, _ := startBaseServices(t, e, traces) + prepareConfigsAndCerts(t, e) + _, token, _ := startBaseServices(t, e) internalOTLPGRPCEndpoint, internalOTLPHTTPEndpoint, httpExternalQueryEndpoint, httpInternalQueryEndpoint := startServicesForTraces(t, e) api, err := newObservatoriumAPIService( @@ -401,12 +401,12 @@ func requestWithRetry(t *testing.T, testLabel string, client *http.Client, reque func TestTracesTemplateQuery(t *testing.T) { t.Parallel() - e, err := e2e.New(e2e.WithName(envTracesTemplateName)) + e, err := e2e.New(e2e.WithName(uniqueE2ENetworkName(t))) testutil.Ok(t, err) t.Cleanup(e.Close) - prepareConfigsAndCerts(t, tracesTemplate, e) - _, token, _ := startBaseServices(t, e, tracesTemplate) + prepareConfigsAndCerts(t, e) + _, token, _ := startBaseServices(t, e) internalOTLPGRPCEndpoint, _, httpExternalQueryEndpoint, httpInternalQueryEndpoint := startServicesForTraces(t, e) api, err := newObservatoriumAPIService( @@ -521,12 +521,12 @@ func TestTracesTemplateQuery(t *testing.T) { func TestTracesTempo(t *testing.T) { t.Parallel() - e, err := e2e.New(e2e.WithName(envTracesTempoName)) + e, err := e2e.New(e2e.WithName(uniqueE2ENetworkName(t))) testutil.Ok(t, err) t.Cleanup(e.Close) - prepareConfigsAndCerts(t, tracesTempo, e) - _, token, _ := startBaseServices(t, e, tracesTempo) + prepareConfigsAndCerts(t, e) + _, token, _ := startBaseServices(t, e) tempoDistributorEndpoint, internalTempoQueryEndpoint, _ := startTempoServicesForTraces(t, e) From 85627d9b12e5ac7ac12ca3459c3e51f24dc37f19 Mon Sep 17 00:00:00 2001 From: Joao Marcal Date: Tue, 31 Mar 2026 11:24:40 +0100 Subject: [PATCH 2/2] e2e: fix Dex token TLS verification for test CA and CI Sign leaves with the parsed CA so AuthorityKeyId matches SubjectKeyId on ca.pem. Add host.docker.internal to Dex/API SANs, set tls.ServerName to the Dex Docker hostname when posting to dex/token, and fail if ca.pem does not parse into the root pool. --- test/e2e/helpers.go | 32 ++++++++++++++++++++++++-------- test/e2e/services.go | 2 +- test/e2e/tenants_test.go | 2 +- test/testtls/generate.go | 13 ++++++++++--- 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/test/e2e/helpers.go b/test/e2e/helpers.go index d7be79b35..e5814faf6 100644 --- a/test/e2e/helpers.go +++ b/test/e2e/helpers.go @@ -23,9 +23,8 @@ import ( ) // uniqueE2ENetworkName returns a Docker-valid e2e network name (≤16 chars, [-a-zA-Z0-9]) -// that is distinct for each Go test. efficientgo/e2e's default name hashes runtime.Caller(3), -// which resolves to testing.tRunner for every test, so bare e2e.New() would assign the same -// network to all parallel tests and reproduce Docker network races. +// that is distinct for each Go test. efficientgo/e2e's bare e2e.New() would assign the same +// network to all parallel tests leading to Docker network races. func uniqueE2ENetworkName(t *testing.T) string { t.Helper() sum := sha256.Sum256([]byte(t.Name())) @@ -39,9 +38,17 @@ func prepareConfigsAndCerts(t *testing.T, e e2e.Environment) { testtls.GenerateCerts( filepath.Join(e.SharedDir(), certsSharedDir), getContainerName(e, "observatorium-api"), - []string{getContainerName(e, "observatorium-api"), "127.0.0.1"}, + []string{ + getContainerName(e, "observatorium-api"), + "127.0.0.1", + "host.docker.internal", + }, getContainerName(e, "dex"), - []string{getContainerName(e, "dex"), "127.0.0.1"}, + []string{ + getContainerName(e, "dex"), + "127.0.0.1", + "host.docker.internal", + }, ), ) @@ -49,11 +56,18 @@ func prepareConfigsAndCerts(t *testing.T, e e2e.Environment) { } // obtainToken obtains a bearer token needed for communication with the API. -func obtainToken(endpoint string, tlsConf *tls.Config) (string, error) { +// dexTLSHost is the Dex DNS name from the test CA (e.g. {network}-dex); set it so TLS verifies the +// server cert when the TCP dial target is 127.0.0.1 or host.docker.internal (e2e.Endpoint). +func obtainToken(endpoint, dexTLSHost string, tlsConf *tls.Config) (string, error) { type token struct { IDToken string `json:"id_token"` } + tlsClient := tlsConf.Clone() + if dexTLSHost != "" { + tlsClient.ServerName = dexTLSHost + } + data := url.Values{} data.Add("grant_type", "password") data.Add("username", "admin@example.com") @@ -70,7 +84,7 @@ func obtainToken(endpoint string, tlsConf *tls.Config) (string, error) { c := &http.Client{ Transport: &http.Transport{ - TLSClientConfig: tlsConf, + TLSClientConfig: tlsClient, }, } @@ -104,7 +118,9 @@ func getTLSClientConfig(t *testing.T, e e2e.Environment) *tls.Config { testutil.Ok(t, err) cp := x509.NewCertPool() - cp.AppendCertsFromPEM(cert) + if ok := cp.AppendCertsFromPEM(cert); !ok { + t.Fatal("failed to parse CA certificate from ca.pem") + } return &tls.Config{ RootCAs: cp, diff --git a/test/e2e/services.go b/test/e2e/services.go index 7652bf815..19065d3a0 100644 --- a/test/e2e/services.go +++ b/test/e2e/services.go @@ -191,7 +191,7 @@ func startBaseServices(t *testing.T, e e2e.Environment) ( createTenantsYAML(t, e, dex.InternalEndpoint("https"), opa.InternalEndpoint("http"), getContainerName(e, "observatorium-api")) - token, err := obtainToken(dex.Endpoint("https"), getTLSClientConfig(t, e)) + token, err := obtainToken(dex.Endpoint("https"), getContainerName(e, "dex"), getTLSClientConfig(t, e)) testutil.Ok(t, err) return dex, token, gubernator.InternalEndpoint("grpc") diff --git a/test/e2e/tenants_test.go b/test/e2e/tenants_test.go index 7bcd35fab..919b16ad2 100644 --- a/test/e2e/tenants_test.go +++ b/test/e2e/tenants_test.go @@ -59,7 +59,7 @@ func TestTenantsRetryAuthenticationProviderRegistration(t *testing.T) { // Restart Dex. testutil.Ok(t, e2e.StartAndWaitReady(dex)) - token, err := obtainToken(dex.Endpoint("https"), getTLSClientConfig(t, e)) + token, err := obtainToken(dex.Endpoint("https"), getContainerName(e, "dex"), getTLSClientConfig(t, e)) testutil.Ok(t, err) up, err := newUpRun( diff --git a/test/testtls/generate.go b/test/testtls/generate.go index 9e04e1d3d..9f2cf8457 100644 --- a/test/testtls/generate.go +++ b/test/testtls/generate.go @@ -65,6 +65,13 @@ func GenerateCerts( return err } + // Use the parsed CA for signing leaves so leaf AuthorityKeyId matches the issued CA's + // SubjectKeyId (the in-memory template may omit fields the encoder adds). + caParsed, err := x509.ParseCertificate(caBytes) + if err != nil { + return fmt.Errorf("parse CA certificate: %w", err) + } + caPEM := new(bytes.Buffer) if err := pem.Encode(caPEM, &pem.Block{ Type: "CERTIFICATE", @@ -88,15 +95,15 @@ func GenerateCerts( key: caPrivKeyPEM.Bytes(), } - apiBundle, err := generateCert(ca, caPrivKey, false, apiCommonName, apiSANs, nil) + apiBundle, err := generateCert(caParsed, caPrivKey, false, apiCommonName, apiSANs, nil) if err != nil { return err } - dexBundle, err := generateCert(ca, caPrivKey, false, dexCommonName, dexSANs, nil) + dexBundle, err := generateCert(caParsed, caPrivKey, false, dexCommonName, dexSANs, nil) if err != nil { return err } - clientBundle, err := generateCert(ca, caPrivKey, true, clientCommonName, []string{clientSANs}, []string{clientGroups}) + clientBundle, err := generateCert(caParsed, caPrivKey, true, clientCommonName, []string{clientSANs}, []string{clientGroups}) if err != nil { return err }