Files
ayatori/internal/bootstrap/options_test.go
T
panxiao81 35ada6d7eb
Verify / test (pull_request) Successful in 11m23s
Verify / lint (pull_request) Successful in 12m18s
Verify / database-integration (pull_request) Successful in 13m49s
feat: 接通 Database 凭据准备闭环
2026-09-27 18:35:13 +00:00

148 lines
5.9 KiB
Go

package bootstrap
import (
"crypto/tls"
"flag"
"slices"
"testing"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
databasev1alpha1 "git.ddupan.top/panxiao81/ayatori/api/database/v1alpha1"
executionv1alpha1 "git.ddupan.top/panxiao81/ayatori/api/execution/v1alpha1"
)
func parseTestOptions(t *testing.T, args ...string) options {
t.Helper()
flags := flag.NewFlagSet("bootstrap-test", flag.ContinueOnError)
var options options
options.bindFlags(flags)
if err := flags.Parse(args); err != nil {
t.Fatal(err)
}
return options
}
func TestDefaultConfiguration(t *testing.T) {
t.Setenv("POD_NAMESPACE", "")
options := parseTestOptions(t)
manager := options.manager.configuration()
if manager.Metrics.BindAddress != "0" || !manager.Metrics.SecureServing || manager.Metrics.FilterProvider == nil {
t.Fatal("metrics defaults or authentication changed")
}
if manager.HealthProbeBindAddress != ":8081" || manager.LeaderElection ||
manager.LeaderElectionID != "a6325ed6.ddupan.top" || manager.LeaderElectionReleaseOnCancel {
t.Fatal("probe or leader election defaults changed")
}
if options.manager.webhookOptions().Port != 9443 || !options.logging.Development {
t.Fatal("webhook or logging defaults changed")
}
if options.database.secretNamespace != "" || options.database.credentialMount != "" || options.openBao.address != "" {
t.Fatal("optional backends enabled by default")
}
if options.openBao.mount != "kubernetes" || options.openBao.identity.Audience != "openbao" {
t.Fatal("OpenBao defaults changed")
}
options.database.configureManager(&manager)
if len(manager.Cache.ByObject) != 0 {
t.Fatal("disabled observation unexpectedly configured Secret cache")
}
for _, object := range []runtime.Object{
&corev1.Secret{}, &corev1.ServiceAccount{}, &executionv1alpha1.Job{},
&databasev1alpha1.PostgreSQLInstance{}, &databasev1alpha1.PostgreSQLDatabase{}, &databasev1alpha1.PostgreSQLTenant{},
} {
if _, _, err := manager.Scheme.ObjectKinds(object); err != nil {
t.Fatalf("missing scheme registration for %T: %v", object, err)
}
}
}
func TestCredentialPreparationOptions(t *testing.T) {
options := parseTestOptions(t, "--database-credential-mount=applications-kv", "--database-credential-prefix=database")
if options.database.credentialMount != "applications-kv" || options.database.credentialPrefix != "database" {
t.Fatal("凭据准备参数未传入领域装配")
}
if err := setupCredentialPreparation(nil, options.database, nil); err == nil {
t.Fatal("启用凭据准备必须有显式配置的认证 client")
}
if err := setupCredentialPreparation(nil, databaseOptions{}, nil); err != nil {
t.Fatal("默认停用凭据准备不应要求后端")
}
}
func TestManagerFlagOverrides(t *testing.T) {
options := parseTestOptions(t,
"--metrics-bind-address=:9090", "--metrics-secure=false", "--health-probe-bind-address=:9091",
"--leader-elect", "--webhook-port=-1", "--metrics-cert-path=/fixture/metrics",
"--metrics-cert-name=server.crt", "--metrics-cert-key=server.key", "--webhook-cert-path=/fixture/webhook",
"--webhook-cert-name=hook.crt", "--webhook-cert-key=hook.key",
)
manager := options.manager.configuration()
if manager.Metrics.BindAddress != ":9090" || manager.Metrics.SecureServing || manager.Metrics.FilterProvider != nil ||
manager.HealthProbeBindAddress != ":9091" || !manager.LeaderElection {
t.Fatal("manager flags not applied")
}
if manager.Metrics.CertDir != "/fixture/metrics" || manager.Metrics.CertName != "server.crt" || manager.Metrics.KeyName != "server.key" {
t.Fatal("metrics certificate flags not applied")
}
webhook := options.manager.webhookOptions()
if webhook.Port != -1 || webhook.CertDir != "/fixture/webhook" || webhook.CertName != "hook.crt" || webhook.KeyName != "hook.key" {
t.Fatal("webhook flags not applied")
}
}
func TestHTTP2Policy(t *testing.T) {
for _, enabled := range []bool{false, true} {
args := []string{}
if enabled {
args = append(args, "--enable-http2")
}
options := parseTestOptions(t, args...)
for _, callbacks := range [][]func(*tls.Config){options.manager.metricsOptions().TLSOpts, options.manager.webhookOptions().TLSOpts} {
config := &tls.Config{NextProtos: []string{"h2", "http/1.1"}}
for _, callback := range callbacks {
callback(config)
}
if slices.Contains(config.NextProtos, "h2") != enabled || !slices.Contains(config.NextProtos, "http/1.1") {
t.Fatal("HTTP/2 policy changed")
}
}
}
}
func TestComponentFlagsAndNamespaceScope(t *testing.T) {
t.Setenv("POD_NAMESPACE", "from-environment")
if parseTestOptions(t).database.secretNamespace != "from-environment" {
t.Fatal("namespace environment default lost")
}
options := parseTestOptions(t,
"--database-secret-namespace=controller", "--database-root-cert=/fixture/postgres-ca.pem",
"--openbao-address=https://bao.example", "--openbao-ca-cert=/fixture/bao-ca.pem",
"--openbao-auth-mount=cluster", "--openbao-auth-role=controller",
"--openbao-service-account-namespace=identity", "--openbao-service-account-name=bao-login",
"--openbao-token-audience=bao",
)
if options.database.secretNamespace != "controller" || options.database.rootCert != "/fixture/postgres-ca.pem" {
t.Fatal("Database flags not applied")
}
bao := options.openBao
if bao.address != "https://bao.example" || bao.caCert != "/fixture/bao-ca.pem" || bao.mount != "cluster" ||
bao.role != "controller" || bao.identity.Namespace != "identity" || bao.identity.ServiceAccount != "bao-login" || bao.identity.Audience != "bao" {
t.Fatal("OpenBao flags not applied")
}
manager := options.manager.configuration()
options.database.configureManager(&manager)
if len(manager.Cache.ByObject) != 1 {
t.Fatal("Secret cache scope missing")
}
for object, config := range manager.Cache.ByObject {
if _, ok := object.(*corev1.Secret); !ok {
t.Fatal("unexpected cache object")
}
if _, ok := config.Namespaces["controller"]; !ok || len(config.Namespaces) != 1 {
t.Fatal("Secret cache escaped explicit namespace")
}
}
}