117 lines
4.4 KiB
Go
117 lines
4.4 KiB
Go
//go:build integration
|
|
|
|
package openbao_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
bao "github.com/openbao/openbao/api/v2"
|
|
corev1 "k8s.io/api/core/v1"
|
|
"k8s.io/apimachinery/pkg/api/meta"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"k8s.io/client-go/rest"
|
|
ctrl "sigs.k8s.io/controller-runtime"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
"sigs.k8s.io/controller-runtime/pkg/envtest"
|
|
|
|
databasev1alpha1 "git.ddupan.top/panxiao81/ayatori/api/database/v1alpha1"
|
|
"git.ddupan.top/panxiao81/ayatori/internal/database/adapter/kubernetes"
|
|
"git.ddupan.top/panxiao81/ayatori/internal/database/application"
|
|
databasecontroller "git.ddupan.top/panxiao81/ayatori/internal/database/controller"
|
|
)
|
|
|
|
const preparationNamespace = "credential-preparation"
|
|
|
|
type preparationFixture struct {
|
|
api client.Client
|
|
config *rest.Config
|
|
scheme *runtime.Scheme
|
|
bao *bao.Client
|
|
}
|
|
|
|
func newPreparationFixture(t *testing.T) *preparationFixture {
|
|
t.Helper()
|
|
environment := &envtest.Environment{CRDDirectoryPaths: []string{"../../../../config/crd/bases"}, ErrorIfCRDPathMissing: true}
|
|
config, err := environment.Start()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() {
|
|
if err := environment.Stop(); err != nil {
|
|
t.Error(err)
|
|
}
|
|
})
|
|
scheme := runtime.NewScheme()
|
|
if err := databasev1alpha1.AddToScheme(scheme); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := corev1.AddToScheme(scheme); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
api, err := client.New(config, client.Options{Scheme: scheme})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := api.Create(t.Context(), &corev1.Namespace{Name: preparationNamespace}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return &preparationFixture{api: api, config: config, scheme: scheme, bao: baoFixture(t)}
|
|
}
|
|
|
|
func (f *preparationFixture) bound(t *testing.T, name string) (*databasev1alpha1.PostgreSQLDatabase, *databasev1alpha1.PostgreSQLTenant) {
|
|
t.Helper()
|
|
instance := &databasev1alpha1.PostgreSQLInstance{Name: name, Spec: databasev1alpha1.PostgreSQLInstanceSpec{
|
|
Endpoint: databasev1alpha1.PostgreSQLEndpoint{Host: "postgres.example", HostAddr: "192.0.2.1"},
|
|
AdminCredentialRef: databasev1alpha1.AdminCredentialReference{Name: "management"},
|
|
}}
|
|
if err := f.api.Create(t.Context(), instance); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// 本切片不连接 PG;这里只声明供应前置观察,真实管理能力由既有 PG 集成测试覆盖。
|
|
meta.SetStatusCondition(&instance.Status.Conditions, metav1.Condition{
|
|
Type: "Ready", Status: metav1.ConditionTrue, Reason: "FixtureReady", Message: "隔离测试前置观察", ObservedGeneration: instance.Generation,
|
|
})
|
|
if err := f.api.Status().Update(t.Context(), instance); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
tenant := &databasev1alpha1.PostgreSQLTenant{Name: name, Namespace: preparationNamespace}
|
|
tenant.Spec.Provision = &databasev1alpha1.DatabaseProvisionRequest{InstanceRef: databasev1alpha1.InstanceReference{Name: databasev1alpha1.ObjectName(name)}}
|
|
if err := f.api.Create(t.Context(), tenant); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
binder := &databasecontroller.BindingReconciler{Client: f.api, Reader: f.api}
|
|
if _, err := binder.Reconcile(t.Context(), ctrl.Request{NamespacedName: client.ObjectKeyFromObject(tenant)}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := f.api.Get(t.Context(), client.ObjectKeyFromObject(tenant), tenant); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
database := &databasev1alpha1.PostgreSQLDatabase{}
|
|
if err := f.api.Get(t.Context(), client.ObjectKey{Name: string(tenant.Status.DatabaseRef.Name)}, database); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return database, tenant
|
|
}
|
|
|
|
func (f *preparationFixture) service(t *testing.T) application.CredentialPreparation {
|
|
t.Helper()
|
|
return application.CredentialPreparation{
|
|
Resources: &kubernetes.CredentialResources{Client: f.api, Reader: f.api}, Store: fixtureStore(t, f.bao),
|
|
}
|
|
}
|
|
|
|
func (f *preparationFixture) status(t *testing.T, database *databasev1alpha1.PostgreSQLDatabase, version int64, reason string) {
|
|
t.Helper()
|
|
if err := f.api.Get(t.Context(), client.ObjectKeyFromObject(database), database); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
condition := meta.FindStatusCondition(database.Status.Conditions, application.CredentialsReady)
|
|
if database.Status.CredentialVersion != version || condition == nil || condition.Reason != reason {
|
|
t.Fatalf("凭据版本或条件不符:version=%d,期望 reason=%s", database.Status.CredentialVersion, reason)
|
|
}
|
|
if meta.IsStatusConditionTrue(database.Status.Conditions, "Ready") {
|
|
t.Fatal("凭据准备不得宣告 Database Ready")
|
|
}
|
|
}
|