feat: 接通 PostgreSQL 角色与数据库创建闭环
This commit is contained in:
@@ -38,6 +38,16 @@ type PostgreSQLDatabaseStatus struct {
|
||||
// +kubebuilder:validation:Minimum=1
|
||||
// +optional
|
||||
CredentialVersion int64 `json:"credentialVersion,omitempty"`
|
||||
// RoleOID 只在角色创建提交并回读成功后保存,后续不按同名认领。
|
||||
// +kubebuilder:validation:Minimum=1
|
||||
// +kubebuilder:validation:Maximum=4294967295
|
||||
// +optional
|
||||
RoleOID int64 `json:"roleOID,omitempty"`
|
||||
// DatabaseOID 只在数据库创建并回读成功后保存;缺失不代表允许认领已有对象。
|
||||
// +kubebuilder:validation:Minimum=1
|
||||
// +kubebuilder:validation:Maximum=4294967295
|
||||
// +optional
|
||||
DatabaseOID int64 `json:"databaseOID,omitempty"`
|
||||
// Phase 暂不冻结供应子阶段枚举;它不是操作授权或绑定的替代记录。
|
||||
// +optional
|
||||
Phase string `json:"phase,omitempty"`
|
||||
@@ -50,6 +60,10 @@ type PostgreSQLDatabaseStatus struct {
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:resource:scope=Cluster
|
||||
// +kubebuilder:validation:XValidation:rule="!has(self.status) || !has(self.status.roleOID) || (has(self.status.credentialVersion) && has(self.status.instanceUID))",message="roleOID requires confirmed credentials and instanceUID"
|
||||
// +kubebuilder:validation:XValidation:rule="!has(self.status) || !has(self.status.databaseOID) || has(self.status.roleOID)",message="databaseOID requires roleOID"
|
||||
// +kubebuilder:validation:XValidation:rule="!(has(oldSelf.status) && has(oldSelf.status.roleOID)) || (has(self.status) && has(self.status.roleOID) && self.status.roleOID == oldSelf.status.roleOID)",message="confirmed roleOID cannot change or be removed"
|
||||
// +kubebuilder:validation:XValidation:rule="!(has(oldSelf.status) && has(oldSelf.status.databaseOID)) || (has(self.status) && has(self.status.databaseOID) && self.status.databaseOID == oldSelf.status.databaseOID)",message="confirmed databaseOID cannot change or be removed"
|
||||
// +kubebuilder:validation:XValidation:rule="!has(self.status) || !has(self.status.credentialVersion) || has(self.status.credentialRef)",message="credentialVersion requires credentialRef"
|
||||
// +kubebuilder:validation:XValidation:rule="!(has(oldSelf.status) && has(oldSelf.status.credentialRef)) || (has(self.status) && has(self.status.credentialRef) && self.status.credentialRef == oldSelf.status.credentialRef)",message="recorded credentialRef cannot change or be removed"
|
||||
// +kubebuilder:validation:XValidation:rule="!(has(oldSelf.status) && has(oldSelf.status.credentialVersion)) || (has(self.status) && has(self.status.credentialVersion) && self.status.credentialVersion == oldSelf.status.credentialVersion)",message="confirmed credentialVersion cannot change or be removed"
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package v1alpha1_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
databasev1alpha1 "git.ddupan.top/panxiao81/ayatori/api/database/v1alpha1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
func testResourceStatus(t *testing.T, api client.Client) {
|
||||
object := validDatabase("resource-status")
|
||||
if err := api.Create(t.Context(), object); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
invalid := object.DeepCopy()
|
||||
invalid.Status.RoleOID = 11
|
||||
if err := api.Status().Update(t.Context(), invalid); !apierrors.IsInvalid(err) {
|
||||
t.Fatal("无凭据不能确认角色", err)
|
||||
}
|
||||
object.Status.InstanceUID = "instance-uid"
|
||||
object.Status.CredentialRef = &databasev1alpha1.CredentialReference{Mount: "application-secrets", Path: "applications/test"}
|
||||
object.Status.CredentialVersion = 1
|
||||
object.Status.RoleOID, object.Status.DatabaseOID = 11, 22
|
||||
if err := api.Status().Update(t.Context(), object); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, change := range []func(*databasev1alpha1.PostgreSQLDatabase){
|
||||
func(d *databasev1alpha1.PostgreSQLDatabase) { d.Status.RoleOID = 0 },
|
||||
func(d *databasev1alpha1.PostgreSQLDatabase) { d.Status.RoleOID = 12 },
|
||||
func(d *databasev1alpha1.PostgreSQLDatabase) { d.Status.DatabaseOID = 0 },
|
||||
func(d *databasev1alpha1.PostgreSQLDatabase) { d.Status.DatabaseOID = 23 },
|
||||
} {
|
||||
invalid = object.DeepCopy()
|
||||
change(invalid)
|
||||
if err := api.Status().Update(t.Context(), invalid); !apierrors.IsInvalid(err) {
|
||||
t.Fatal("已确认 OID 不得覆盖或移除", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,7 @@ func TestDatabaseAPI(t *testing.T) {
|
||||
t.Run("拒绝非法声明", func(t *testing.T) { testInvalidDeclarations(t, client) })
|
||||
t.Run("status隔离和绑定并发", func(t *testing.T) { testBindingWrites(t, client) })
|
||||
t.Run("凭据位置与确认版本", func(t *testing.T) { testCredentialStatus(t, client) })
|
||||
t.Run("资源创建确认", func(t *testing.T) { testResourceStatus(t, client) })
|
||||
t.Run("仓库示例", func(t *testing.T) { testSamples(t, client, scheme) })
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user