diff --git a/controllers/account/main.go b/controllers/account/main.go index bb96316a18c..00121fae0c6 100644 --- a/controllers/account/main.go +++ b/controllers/account/main.go @@ -33,6 +33,7 @@ import ( rate "github.com/labring/sealos/controllers/pkg/utils/rate" userv1 "github.com/labring/sealos/controllers/user/api/v1" + kbv1alpha1 "github.com/apecloud/kubeblocks/apis/apps/v1alpha1" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" @@ -61,7 +62,7 @@ func init() { utilruntime.Must(accountv1.AddToScheme(scheme)) utilruntime.Must(userv1.AddToScheme(scheme)) utilruntime.Must(notificationv1.AddToScheme(scheme)) - //utilruntime.Must(kbv1alpha1.SchemeBuilder.AddToScheme(scheme)) + utilruntime.Must(kbv1alpha1.SchemeBuilder.AddToScheme(scheme)) //+kubebuilder:scaffold:scheme } diff --git a/controllers/pkg/resources/named.go b/controllers/pkg/resources/named.go index b194a0d0c16..fac58c85668 100644 --- a/controllers/pkg/resources/named.go +++ b/controllers/pkg/resources/named.go @@ -53,6 +53,7 @@ const ( ACMEChallengeKey = "acme.cert-manager.io/http01-solver" KubeBlocksBackUpName = "kubeblocks-backup-data" dataProtectionBackupRepoKey = "dataprotection.kubeblocks.io/backup-repo-name" + InstanceLabelKey = "app.kubernetes.io/instance" ) type ResourceNamed struct { @@ -68,6 +69,12 @@ func NewResourceNamed(cr client.Object) *ResourceNamed { labels := cr.GetLabels() p := &ResourceNamed{labels: labels} switch { + case cr.GetName() == KubeBlocksBackUpName || labels[dataProtectionBackupRepoKey] != "": + p._type = DBBackup + p._name = KubeBlocksBackUpName + if labels[InstanceLabelKey] != "" { + p._name = labels[InstanceLabelKey] + } case labels[DBPodLabelComponentNameKey] != "": p._type = DB p._name = labels[DBPodLabelInstanceKey] @@ -86,9 +93,6 @@ func NewResourceNamed(cr client.Object) *ResourceNamed { case labels[ACMEChallengeKey] != "": p._type = APP p._name = getACMEResolverName(cr) - case cr.GetName() == KubeBlocksBackUpName || labels[dataProtectionBackupRepoKey] != "": - p._type = JOB - p._name = KubeBlocksBackUpName default: p._type = OTHER p._name = "" diff --git a/controllers/pkg/resources/resources.go b/controllers/pkg/resources/resources.go index d93e660c3e4..1ecf75de3c4 100644 --- a/controllers/pkg/resources/resources.go +++ b/controllers/pkg/resources/resources.go @@ -163,6 +163,7 @@ const ( objectStorage cvm appStore + dbBackup ) const ( @@ -174,14 +175,15 @@ const ( ObjectStorage = "OBJECT-STORAGE" CVM = "CLOUD-VM" AppStore = "APP-STORE" + DBBackup = "DB-BACKUP" ) var AppType = map[string]uint8{ - DB: db, APP: app, TERMINAL: terminal, JOB: job, OTHER: other, ObjectStorage: objectStorage, CVM: cvm, AppStore: appStore, + DB: db, APP: app, TERMINAL: terminal, JOB: job, OTHER: other, ObjectStorage: objectStorage, CVM: cvm, AppStore: appStore, DBBackup: dbBackup, } var AppTypeReverse = map[uint8]string{ - db: DB, app: APP, terminal: TERMINAL, job: JOB, other: OTHER, objectStorage: ObjectStorage, cvm: CVM, appStore: AppStore, + db: DB, app: APP, terminal: TERMINAL, job: JOB, other: OTHER, objectStorage: ObjectStorage, cvm: CVM, appStore: AppStore, dbBackup: DBBackup, } // resource consumption diff --git a/controllers/resources/controllers/monitor_controller.go b/controllers/resources/controllers/monitor_controller.go index 15fa69e4ee2..dfc55a7b97d 100644 --- a/controllers/resources/controllers/monitor_controller.go +++ b/controllers/resources/controllers/monitor_controller.go @@ -29,6 +29,8 @@ import ( appv1 "github.com/labring/sealos/controllers/app/api/v1" + kbv1alpha1 "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" + "golang.org/x/sync/errgroup" "github.com/labring/sealos/controllers/pkg/utils/env" @@ -112,6 +114,8 @@ const ( //+kubebuilder:rbac:groups=core,resources=services/status,verbs=get;list;watch //+kubebuilder:rbac:groups=app.sealos.io,resources=instances,verbs=get;list;watch //+kubebuilder:rbac:groups=app.sealos.io,resources=instances/status,verbs=get;list;watch +//+kubebuilder:rbac:groups=dataprotection.apecloud.io,resources=backups,verbs=get;list;watch +//+kubebuilder:rbac:groups=dataprotection.apecloud.io,resources=backups/status,verbs=get;list;watch func NewMonitorReconciler(mgr ctrl.Manager) (*MonitorReconciler, error) { r := &MonitorReconciler{ @@ -146,6 +150,12 @@ func InitIndexField(mgr ctrl.Manager) error { }); err != nil { return err } + if err := mgr.GetFieldIndexer().IndexField(context.Background(), &kbv1alpha1.Backup{}, "status.phase", func(rawObj client.Object) []string { + backup := rawObj.(*kbv1alpha1.Backup) + return []string{string(backup.Status.Phase)} + }); err != nil { + return err + } return mgr.GetFieldIndexer().IndexField(context.Background(), &corev1.Service{}, "spec.type", func(rawObj client.Object) []string { svc := rawObj.(*corev1.Service) return []string{string(svc.Spec.Type)} @@ -434,20 +444,26 @@ func (r *MonitorReconciler) monitorPVCResourceUsage(namespace string, resUsed ma } func (r *MonitorReconciler) monitorDatabaseBackupUsage(namespace string, resUsed map[string]map[corev1.ResourceName]*quantity, resNamed map[string]*resources.ResourceNamed) error { - if r.ObjStorageUserBackupSize == nil { - return nil + backupList := &kbv1alpha1.BackupList{} + if err := r.List(context.Background(), backupList, &client.ListOptions{ + Namespace: namespace, + FieldSelector: fields.OneTermEqualSelector("status.phase", string(kbv1alpha1.BackupPhaseCompleted)), + }); err != nil { + return fmt.Errorf("failed to list backup: %v", err) } - backupSize := r.ObjStorageUserBackupSize[getBackupObjectStorageName(namespace)] - if backupSize <= 0 { + if len(backupList.Items) == 0 { return nil } - - backupRes := resources.NewObjStorageResourceNamed("DB-BACKUP") - if resUsed[backupRes.String()] == nil { - resNamed[backupRes.String()] = backupRes - resUsed[backupRes.String()] = initResources() + for i := range backupList.Items { + backup := &backupList.Items[i] + backupRes := resources.NewResourceNamed(backup) + fmt.Printf("backup name: %v, backup size: %v, backupRes: %s \n", backupList.Items[i].Name, backupList.Items[i].Status.TotalSize, backupRes.String()) + if resUsed[backupRes.String()] == nil { + resNamed[backupRes.String()] = backupRes + resUsed[backupRes.String()] = initResources() + } + resUsed[backupRes.String()][corev1.ResourceStorage].Add(resource.MustParse(backup.Status.TotalSize)) } - resUsed[backupRes.String()][corev1.ResourceStorage].Add(*resource.NewQuantity(backupSize, resource.BinarySI)) return nil } @@ -481,10 +497,6 @@ func (r *MonitorReconciler) monitorServiceResourceUsage(namespace string, resUse return nil } -func getBackupObjectStorageName(namespace string) string { - return strings.TrimPrefix(namespace, "ns-") -} - func (r *MonitorReconciler) getResourceUsed(podResource map[corev1.ResourceName]*quantity) (bool, map[uint8]int64) { used := map[uint8]int64{} isEmpty := true @@ -563,11 +575,12 @@ func (r *MonitorReconciler) handlerObjectStorageTrafficUsed(startTime, endTime t if err != nil { return fmt.Errorf("failed to get object storage flow: %w", err) } - unit := r.Properties.StringMap[resources.ResourceNetwork].Unit - used := int64(math.Ceil(float64(resource.NewQuantity(bytes, resource.BinarySI).MilliValue()) / float64(unit.MilliValue()))) - if used <= 0 { + // Because the obtained traffic includes traffic communicating with the controller, filter out traffic smaller than 1 MB + if bytes < 1024*1024 { return nil } + unit := r.Properties.StringMap[resources.ResourceNetwork].Unit + used := int64(math.Ceil(float64(resource.NewQuantity(bytes, resource.BinarySI).MilliValue()) / float64(unit.MilliValue()))) namespace := "ns-" + strings.SplitN(bucket, "-", 2)[0] ro := resources.Monitor{ diff --git a/controllers/resources/deploy/manifests/deploy.yaml b/controllers/resources/deploy/manifests/deploy.yaml index 3ab1fdcfebc..9f99ddc571b 100644 --- a/controllers/resources/deploy/manifests/deploy.yaml +++ b/controllers/resources/deploy/manifests/deploy.yaml @@ -149,6 +149,22 @@ rules: - get - list - watch +- apiGroups: + - dataprotection.kubeblocks.io + resources: + - backups + verbs: + - get + - list + - watch +- apiGroups: + - dataprotection.kubeblocks.io + resources: + - backups/status + verbs: + - get + - list + - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole diff --git a/controllers/resources/main.go b/controllers/resources/main.go index ff26ecbe530..5677a77078a 100644 --- a/controllers/resources/main.go +++ b/controllers/resources/main.go @@ -31,6 +31,8 @@ import ( "github.com/labring/sealos/controllers/pkg/resources" "github.com/labring/sealos/controllers/pkg/utils/env" + "github.com/apecloud/kubeblocks/apis/dataprotection/v1alpha1" + appv1 "github.com/labring/sealos/controllers/app/api/v1" "github.com/labring/sealos/controllers/resources/controllers" @@ -54,6 +56,7 @@ var ( func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(appv1.AddToScheme(scheme)) + utilruntime.Must(v1alpha1.AddToScheme(scheme)) //+kubebuilder:scaffold:scheme }