Instance 阶段性基线:Ready 初版与领域设计 #6

Merged
panxiao81 merged 8 commits from feature/openbao-adapter into main 2026-09-13 15:26:36 +00:00
Owner

合并范围

结束本 PR 的长期迭代,保留阶段性代码与已确认设计,后续实现使用独立、小范围 PR。

  • 保留早期 PostgreSQLInstance Ready 实现、状态机调整及 PostgreSQL/OpenBao E2E fixture。
  • 保留尚未接线的 Instance 连接生命周期 service,作为待替换的过渡实现,不代表 DDD 模型已实现。
  • 新增 Instance 领域对象规格:领域对象只接收观察值、执行规则和状态决策,不访问外部 IO。
  • 确认管理凭据来自 controller namespace 的 Secret,由管理员维护 ExternalSecret、ESO 同步;用户名或密码变化时重建连接池,不修改 PG 密码。
  • 确认 Instance 身份/endpoint 以管理员声明为准,以及 finalizer 阻止有 Tenant 引用的 Instance 删除。

当前限制

代码仍使用早期 Bao 管理凭据路径,API types、连接装配和删除实现尚未对齐最新文档。此 PR 不是新领域模型或 Secret 连接方案的完成声明,不应据此部署为符合全部规格的版本。

后续先实现 Instance 纯领域模型及测试,再分小 PR 接入适配器和应用用例;不在本 PR 继续堆叠重构。Tenant 设计未在本轮展开。

验证

既有代码本地 lint 曾通过;本批文档 git diff --check 通过。未在本轮运行完整测试或 E2E,CI 状态以具体提交检查为准。

Refs #1

## 合并范围 结束本 PR 的长期迭代,保留阶段性代码与已确认设计,后续实现使用独立、小范围 PR。 - 保留早期 PostgreSQLInstance Ready 实现、状态机调整及 PostgreSQL/OpenBao E2E fixture。 - 保留尚未接线的 Instance 连接生命周期 service,作为待替换的过渡实现,不代表 DDD 模型已实现。 - 新增 Instance 领域对象规格:领域对象只接收观察值、执行规则和状态决策,不访问外部 IO。 - 确认管理凭据来自 controller namespace 的 Secret,由管理员维护 ExternalSecret、ESO 同步;用户名或密码变化时重建连接池,不修改 PG 密码。 - 确认 Instance 身份/endpoint 以管理员声明为准,以及 finalizer 阻止有 Tenant 引用的 Instance 删除。 ## 当前限制 代码仍使用早期 Bao 管理凭据路径,API types、连接装配和删除实现尚未对齐最新文档。此 PR 不是新领域模型或 Secret 连接方案的完成声明,不应据此部署为符合全部规格的版本。 后续先实现 Instance 纯领域模型及测试,再分小 PR 接入适配器和应用用例;不在本 PR 继续堆叠重构。Tenant 设计未在本轮展开。 ## 验证 既有代码本地 lint 曾通过;本批文档 git diff --check 通过。未在本轮运行完整测试或 E2E,CI 状态以具体提交检查为准。 Refs #1
panxiao81 added 3 commits 2026-09-10 18:16:12 +00:00
test: verify Instance readiness end to end
E2E Tests / Run on Ubuntu (pull_request) Failing after 1m6s
Tests / Run on Ubuntu (pull_request) Successful in 3m55s
Lint / Run on Ubuntu (pull_request) Successful in 4m19s
212ca4be99
@@ -62,6 +72,12 @@ func (r *PostgreSQLInstanceReconciler) Reconcile(ctx context.Context, req ctrl.R
setReconcilingCondition(&instance.Status.Conditions, instance.Generation, phaseResult.reconcilingMessage)
}
var reconcileErr error
Author
Owner

这里我理解是基于状态决定状态机动作,那代码也应该扔进状态机而不是在这里

这里我理解是基于状态决定状态机动作,那代码也应该扔进状态机而不是在这里
@@ -0,0 +76,4 @@
// New validates config and constructs an Initializer.
func New(config Config) (*Initializer, error) {
if config.OpenBaoAddress == "" || config.OpenBaoAuthRole == "" || config.OpenBaoAuthMount == "" ||
Author
Owner

我们要不要用经典spf13的两件套?
不过已经搞了DI,viper的收益不大了

我们要不要用经典spf13的两件套? 不过已经搞了DI,viper的收益不大了
@@ -0,0 +139,4 @@
ctx, cancel := context.WithTimeout(ctx, i.config.Timeout)
defer cancel()
clientConfig := openbao.DefaultConfig()
Author
Owner

可能我Spring用太多了总有一种这种Config应该配合Config来源动态注册进来的感觉
然后client本身的话也作为单例。。。但单例不一定是对的嗷

可能我Spring用太多了总有一种这种Config应该配合Config来源动态注册进来的感觉 然后client本身的话也作为单例。。。但单例不一定是对的嗷
Author
Owner

连接数据库本身为什么需要配置openbao?这个数据库凭据可能放在openbao,但是会有eso来同步secret,应用应当还是传统方式从env或配置文件来拿这个连接信息

连接数据库本身为什么需要配置openbao?这个数据库凭据可能放在openbao,但是会有eso来同步secret,应用应当还是传统方式从env或配置文件来拿这个连接信息
@@ -0,0 +147,4 @@
if err != nil {
return nil, dependencyFailure("create OpenBao client")
}
auth, err := kubernetesauth.NewKubernetesAuth(
Author
Owner

这地方还有初始化Kubernetes的部分,这些代码不该在这里吧

这地方还有初始化Kubernetes的部分,这些代码不该在这里吧
@@ -64,2 +68,4 @@
var externalSecretStoreName, postgreSQLCABundlePath string
var reconcileTimeout time.Duration
var tlsOpts []func(*tls.Config)
flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+
Author
Owner

是不是应该评估一下要不要引入SPF13两件套

是不是应该评估一下要不要引入SPF13两件套
cmd/main.go Outdated
@@ -90,0 +115,4 @@
PostgreSQLCABundlePath: postgreSQLCABundlePath, Timeout: reconcileTimeout,
})
if err != nil {
setupLog.Error(err, "Invalid controller dependency configuration")
Author
Owner

话说log库是?

话说log库是?
panxiao81 marked this conversation as resolved
cmd/main.go Outdated
@@ -181,3 +213,2 @@
if err := (&controller.PostgreSQLInstanceReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Client: mgr.GetClient(), Scheme: mgr.GetScheme(), Initializer: instanceInitializer, Timeout: reconcileTimeout,
Author
Owner

写一行这可读性有点差了

写一行这可读性有点差了
@@ -63,6 +63,9 @@ spec:
args:
- --leader-elect
- --health-probe-bind-address=:8081
- --openbao-address=https://openbao.openbao.svc:8200
Author
Owner

死的配置文件?绑定环境了?环境信息应该在ci注入吧

死的配置文件?绑定环境了?环境信息应该在ci注入吧
@@ -37,0 +35,4 @@
| `--openbao-auth-mount` | `kubernetes` | Kubernetes auth mount 名称 |
| `--openbao-auth-role` | 必填 | controller ServiceAccount 对应 role |
| `--openbao-kv-mount` | `kv` | KV v2 mount;开发可显式用 `secret` |
| `--openbao-service-account-token-path` | `/var/run/secrets/kubernetes.io/serviceaccount/token` | Kubernetes auth 使用的投射 token 文件 |
Author
Owner

这是?这东西需要一个参数吗?

这是?这东西需要一个参数吗?
@@ -75,0 +90,4 @@
return ctrl.Result{}, reconcileErr
}
func (r *PostgreSQLInstanceReconciler) reconcileDependencies(
Author
Owner

同上这个函数应该也是状态机吧

同上这个函数应该也是状态机吧
@@ -0,0 +87,4 @@
if config.OpenBaoConsumerAddress == "" {
config.OpenBaoConsumerAddress = config.OpenBaoAddress
}
if err := validateAddress(config.OpenBaoConsumerAddress); err != nil {
Author
Owner

所以你这到底是instance的初始化代码放在这里还是把整个控制器的初始化代码扔这里了?

所以你这到底是instance的初始化代码放在这里还是把整个控制器的初始化代码扔这里了?
@@ -0,0 +126,4 @@
return "", privilegeFailure("initialize PostgreSQL registry")
}
var version string
if err := pool.QueryRow(ctx, "SHOW server_version").Scan(&version); err != nil {
Author
Owner

你看你重新实现了一遍上面的Validate,你到底想要验证什么?

你看你重新实现了一遍上面的Validate,你到底想要验证什么?
@@ -0,0 +193,4 @@
pool.Close()
return nil, authenticationFailure("authenticate to PostgreSQL")
}
return pool, nil
Author
Owner

woc从这里往上是一串超长的面向过程面条代码,很多validate的逻辑应该都不要

woc从这里往上是一串超长的面向过程面条代码,很多validate的逻辑应该都不要
Author
Owner

还是面向过程的面条

还是面向过程的面条
@@ -0,0 +196,4 @@
return pool, nil
}
func validateAddress(value string) error {
Author
Owner

你告诉我加一条校验有效http url有什么意义

你告诉我加一条校验有效http url有什么意义
@@ -0,0 +205,4 @@
return nil
}
func validateRelativePath(value string, rejectAPILayer bool) error {
Author
Owner

同理

同理
panxiao81 added 1 commit 2026-09-11 15:12:04 +00:00
refactor: consolidate Instance phase handlers
E2E Tests / Run on Ubuntu (pull_request) Failing after 1m28s
Tests / Run on Ubuntu (pull_request) Successful in 4m35s
Lint / Run on Ubuntu (pull_request) Successful in 4m58s
89d9e2316b
@@ -41,3 +46,3 @@
func (m instanceStateMachine) reconcile(instance *databasev1alpha1.PostgreSQLInstance) instancePhaseResult {
func (m *instanceStateMachine) reconcile(ctx context.Context, instance *databasev1alpha1.PostgreSQLInstance) (ctrl.Result, error) {
phase := instance.Status.Phase
Author
Owner

这里可读性差了点,稍微补一下注释

这里可读性差了点,稍微补一下注释
@@ -59,3 +71,1 @@
phase: databasev1alpha1.PostgreSQLInstancePhaseValidating,
reconcilingMessage: "instance dependencies are being validated",
}
func (m *instanceStateMachine) pending(_ context.Context, instance *databasev1alpha1.PostgreSQLInstance) (ctrl.Result, error) {
Author
Owner

虽然嘛返回result也很正常,但是这里要注意的是上面的代码做完了读取状态-》决定动作这一步,那么每一步内要做的事情剩下处理状态-〉进行状态转移,这是标准的状态机实现。

虽然嘛返回result也很正常,但是这里要注意的是上面的代码做完了读取状态-》决定动作这一步,那么每一步内要做的事情剩下处理状态-〉进行状态转移,这是标准的状态机实现。
@@ -66,2 +76,2 @@
phase: databasev1alpha1.PostgreSQLInstancePhaseDeleting,
reconcilingMessage: "instance deletion is reconciling",
func (m *instanceStateMachine) validate(ctx context.Context, instance *databasev1alpha1.PostgreSQLInstance) (ctrl.Result, error) {
if m.initializer == nil {
Author
Owner

这不能说是坏习惯,但我想知道他什么时候会为null

这不能说是坏习惯,但我想知道他什么时候会为null
@@ -27,3 +29,3 @@
type instanceStateMachine struct {
handlers map[databasev1alpha1.PostgreSQLInstancePhase]instancePhaseHandler
initializer PostgreSQLInstanceInitializer
Author
Owner

我不理解为什么是initializer,这不是就是postgresqlinstance的domain对象吗?ddd呢?初始化一看就很面向过程啊

我不理解为什么是initializer,这不是就是postgresqlinstance的domain对象吗?ddd呢?初始化一看就很面向过程啊
Author
Owner

名字?

名字?
@@ -0,0 +90,4 @@
if err := validateAddress(config.OpenBaoConsumerAddress); err != nil {
return nil, err
}
if !filepath.IsAbs(config.ServiceAccountTokenPath) || validateRelativePath(config.OpenBaoAuthMount, false) != nil ||
Author
Owner

按说initializer初始化比较后期,这时候校验openbao配置?这个配置校验不应该注入配置的时候就做好吗?说的比较复杂一点就是当配置无效这个配置类就不该被创建,然后fatal直接崩溃掉

按说initializer初始化比较后期,这时候校验openbao配置?这个配置校验不应该注入配置的时候就做好吗?说的比较复杂一点就是当配置无效这个配置类就不该被创建,然后fatal直接崩溃掉
panxiao81 added 1 commit 2026-09-11 16:12:09 +00:00
refactor: introduce Instance connection lifecycle service
E2E Tests / Run on Ubuntu (pull_request) Failing after 44s
Tests / Run on Ubuntu (pull_request) Successful in 3m56s
Lint / Run on Ubuntu (pull_request) Successful in 4m18s
59303f5276
panxiao81 force-pushed feature/openbao-adapter from a4d835e612 to 0c8edaa8de 2026-09-11 16:12:09 +00:00 Compare
panxiao81 force-pushed feature/openbao-adapter from 0c8edaa8de to 59303f5276 2026-09-11 16:22:04 +00:00 Compare
@@ -37,6 +38,7 @@ import (
databasev1alpha1 "git.ddupan.top/panxiao81/postgresql-tenant-operator/api/v1alpha1"
"git.ddupan.top/panxiao81/postgresql-tenant-operator/internal/controller"
instanceinitializer "git.ddupan.top/panxiao81/postgresql-tenant-operator/internal/instance"
Author
Owner

名字没改

名字没改
panxiao81 added 1 commit 2026-09-13 12:17:48 +00:00
docs: define Instance domain model and admin Secret boundary
E2E Tests / Run on Ubuntu (pull_request) Failing after 1m21s
Tests / Run on Ubuntu (pull_request) Successful in 4m12s
Lint / Run on Ubuntu (pull_request) Successful in 4m37s
953878ac47
panxiao81 added 1 commit 2026-09-13 15:06:11 +00:00
docs: define management connection refresh on Secret changes
E2E Tests / Run on Ubuntu (pull_request) Failing after 1m14s
Tests / Run on Ubuntu (pull_request) Successful in 4m27s
Lint / Run on Ubuntu (pull_request) Successful in 4m47s
a0afbf992c
panxiao81 added 1 commit 2026-09-13 15:25:48 +00:00
docs: clarify Instance identity and deletion semantics
E2E Tests / Run on Ubuntu (pull_request) Failing after 38s
Tests / Run on Ubuntu (pull_request) Successful in 6m52s
Lint / Run on Ubuntu (pull_request) Successful in 8m23s
bb87316773
panxiao81 changed title from feat: 实现 PostgreSQLInstance Ready 纵向链路 to Instance 阶段性基线:Ready 初版与领域设计 2026-09-13 15:26:16 +00:00
panxiao81 merged commit 012efc1581 into main 2026-09-13 15:26:36 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: panxiao81/postgresql-tenant-operator#6