78 lines
2.7 KiB
Go
78 lines
2.7 KiB
Go
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}
|
|
}
|