feat: 接入 Instance 原生管理观测与删除保护
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
databasev1alpha1 "git.ddupan.top/panxiao81/ayatori/api/database/v1alpha1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/cache"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/handler"
|
||||
)
|
||||
|
||||
// InstanceCacheOptions 必须在创建 manager 时使用;只 watch 固定 namespace 的 Secret metadata。
|
||||
// SecretCredentials 始终直读 API,不会令共享 cache 保存密码。
|
||||
func InstanceCacheOptions(namespace string) cache.Options {
|
||||
return cache.Options{ByObject: map[client.Object]cache.ByObject{
|
||||
&corev1.Secret{}: {Namespaces: map[string]cache.Config{namespace: {}}},
|
||||
}}
|
||||
}
|
||||
|
||||
func (r *InstanceReconciler) SetupWithManager(manager ctrl.Manager) error {
|
||||
if r.Observer == nil || len(validation.IsDNS1123Label(r.SecretNamespace)) != 0 {
|
||||
return errors.New("instance observer and valid management Secret namespace required")
|
||||
}
|
||||
if r.Client == nil {
|
||||
r.Client = manager.GetClient()
|
||||
}
|
||||
if r.Reader == nil {
|
||||
r.Reader = manager.GetAPIReader()
|
||||
}
|
||||
return ctrl.NewControllerManagedBy(manager).
|
||||
Named("database-instance").
|
||||
For(&databasev1alpha1.PostgreSQLInstance{}).
|
||||
WatchesMetadata(&corev1.Secret{}, handler.EnqueueRequestsFromMapFunc(r.instancesForSecret)).
|
||||
Watches(&databasev1alpha1.PostgreSQLDatabase{}, handler.EnqueueRequestsFromMapFunc(r.instanceForReference)).
|
||||
Watches(&databasev1alpha1.PostgreSQLTenant{}, handler.EnqueueRequestsFromMapFunc(r.instanceForReference)).
|
||||
Complete(r)
|
||||
}
|
||||
|
||||
func (r *InstanceReconciler) instancesForSecret(ctx context.Context, object client.Object) []ctrl.Request {
|
||||
if object.GetNamespace() != r.SecretNamespace {
|
||||
return nil
|
||||
}
|
||||
instances := &databasev1alpha1.PostgreSQLInstanceList{}
|
||||
if err := r.Client.List(ctx, instances); err != nil {
|
||||
ctrl.LoggerFrom(ctx).Error(err, "无法映射管理 Secret 事件;等待低频重试")
|
||||
return nil
|
||||
}
|
||||
var requests []ctrl.Request
|
||||
for _, item := range instances.Items {
|
||||
if string(item.Spec.AdminCredentialRef.Name) == object.GetName() {
|
||||
request := ctrl.Request{Name: item.Name}
|
||||
requests = append(requests, request)
|
||||
}
|
||||
}
|
||||
return requests
|
||||
}
|
||||
|
||||
func (r *InstanceReconciler) instanceForReference(_ context.Context, object client.Object) []ctrl.Request {
|
||||
var name string
|
||||
switch item := object.(type) {
|
||||
case *databasev1alpha1.PostgreSQLDatabase:
|
||||
name = string(item.Spec.InstanceRef.Name)
|
||||
case *databasev1alpha1.PostgreSQLTenant:
|
||||
if item.Spec.Provision != nil {
|
||||
name = string(item.Spec.Provision.InstanceRef.Name)
|
||||
}
|
||||
}
|
||||
if name == "" {
|
||||
return nil
|
||||
}
|
||||
request := ctrl.Request{Name: name}
|
||||
return []ctrl.Request{request}
|
||||
}
|
||||
Reference in New Issue
Block a user