]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Object gateway inventory card incorrect Buckets and user count 53239/head
authorAashish Sharma <aasharma@li-e74156cc-2f67-11b2-a85c-e98659a63c5c.ibm.com>
Thu, 31 Aug 2023 10:46:32 +0000 (16:16 +0530)
committerAashish Sharma <aasharma@li-e74156cc-2f67-11b2-a85c-e98659a63c5c.ibm.com>
Fri, 1 Sep 2023 06:33:14 +0000 (12:03 +0530)
Inventory(Buckets and users) data is wrong when you have buckets across multiple daemons.

Fixes: https://tracker.ceph.com/issues/62565
Signed-off-by: Aashish Sharma <aasharma@redhat.com>
src/pybind/mgr/dashboard/controllers/rgw.py
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-overview-dashboard/rgw-overview-dashboard.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-overview-dashboard/rgw-overview-dashboard.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-bucket.service.ts

index 766c8eadc51e5e0dfce117ab8d6dab5c2877c196..f7fdfef3f5829b07fafa22e729aeb8598fac2b5a 100644 (file)
@@ -439,6 +439,27 @@ class RgwBucket(RgwRESTController):
         return CephService.get_encryption_config(daemon_name)
 
 
+@UIRouter('/rgw/bucket', Scope.RGW)
+class RgwBucketUi(RgwBucket):
+    @Endpoint('GET')
+    @ReadPermission
+    # pylint: disable=W0613
+    def buckets_and_users_count(self, daemon_name=None):
+        buckets_count = 0
+        users_count = 0
+        daemon_object = RgwDaemon()
+        daemons = json.loads(daemon_object.list())
+        for daemon in daemons:
+            buckets = json.loads(RgwBucket.list(self, daemon_name=daemon['id']))
+            users = json.loads(RgwUser.list(self, daemon_name=daemon['id']))
+            users_count += len(users)
+            buckets_count += len(buckets)
+        return {
+            'buckets_count': buckets_count,
+            'users_count': users_count
+        }
+
+
 @APIRouter('/rgw/user', Scope.RGW)
 @APIDoc("RGW User Management API", "RgwUser")
 class RgwUser(RgwRESTController):
index b419613d4a07f42b414cff0a52c7f75b8ba4cbd0..d691788f0522e3f06f9a8bc9e9f6787217c1ff1e 100644 (file)
@@ -10,7 +10,6 @@ import { RgwRealmService } from '~/app/shared/api/rgw-realm.service';
 import { RgwZonegroupService } from '~/app/shared/api/rgw-zonegroup.service';
 import { RgwZoneService } from '~/app/shared/api/rgw-zone.service';
 import { RgwBucketService } from '~/app/shared/api/rgw-bucket.service';
-import { RgwUserService } from '~/app/shared/api/rgw-user.service';
 import { HealthService } from '~/app/shared/api/health.service';
 import { CardRowComponent } from '~/app/shared/components/card-row/card-row.component';
 import { CardComponent } from '~/app/shared/components/card/card.component';
@@ -46,73 +45,10 @@ describe('RgwOverviewDashboardComponent', () => {
     zones: ['zone4', 'zone5', 'zone6', 'zone7']
   };
 
-  const bucketList = [
-    {
-      bucket: 'bucket',
-      owner: 'testid',
-      usage: {
-        'rgw.main': {
-          size_actual: 4,
-          num_objects: 2
-        },
-        'rgw.none': {
-          size_actual: 6,
-          num_objects: 6
-        }
-      },
-      bucket_quota: {
-        max_size: 20,
-        max_objects: 10,
-        enabled: true
-      }
-    },
-    {
-      bucket: 'bucket2',
-      owner: 'testid',
-      usage: {
-        'rgw.main': {
-          size_actual: 4,
-          num_objects: 2
-        },
-        'rgw.none': {
-          size_actual: 6,
-          num_objects: 6
-        }
-      },
-      bucket_quota: {
-        max_size: 20,
-        max_objects: 10,
-        enabled: true
-      }
-    }
-  ];
-
-  const userList = [
-    {
-      user_id: 'testid',
-      stats: {
-        size_actual: 6,
-        num_objects: 6
-      },
-      user_quota: {
-        max_size: 20,
-        max_objects: 10,
-        enabled: true
-      }
-    },
-    {
-      user_id: 'testid2',
-      stats: {
-        size_actual: 6,
-        num_objects: 6
-      },
-      user_quota: {
-        max_size: 20,
-        max_objects: 10,
-        enabled: true
-      }
-    }
-  ];
+  const bucketAndUserList = {
+    buckets_count: 2,
+    users_count: 2
+  };
 
   const healthData = {
     total_objects: '290',
@@ -124,7 +60,6 @@ describe('RgwOverviewDashboardComponent', () => {
   let listZonegroupsSpy: jest.SpyInstance;
   let listRealmsSpy: jest.SpyInstance;
   let listBucketsSpy: jest.SpyInstance;
-  let listUsersSpy: jest.SpyInstance;
   let healthDataSpy: jest.SpyInstance;
 
   beforeEach(async () => {
@@ -152,9 +87,8 @@ describe('RgwOverviewDashboardComponent', () => {
       .mockReturnValue(of(zonegroupList));
     listZonesSpy = jest.spyOn(TestBed.inject(RgwZoneService), 'list').mockReturnValue(of(zoneList));
     listBucketsSpy = jest
-      .spyOn(TestBed.inject(RgwBucketService), 'list')
-      .mockReturnValue(of(bucketList));
-    listUsersSpy = jest.spyOn(TestBed.inject(RgwUserService), 'list').mockReturnValue(of(userList));
+      .spyOn(TestBed.inject(RgwBucketService), 'getTotalBucketsAndUsersLength')
+      .mockReturnValue(of(bucketAndUserList));
     healthDataSpy = jest
       .spyOn(TestBed.inject(HealthService), 'getClusterCapacity')
       .mockReturnValue(of(healthData));
@@ -196,10 +130,6 @@ describe('RgwOverviewDashboardComponent', () => {
   it('should get corresponding data into Buckets', () => {
     expect(listBucketsSpy).toHaveBeenCalled();
     expect(component.rgwBucketCount).toEqual(2);
-  });
-
-  it('should get corresponding data into Users', () => {
-    expect(listUsersSpy).toHaveBeenCalled();
     expect(component.UserCount).toEqual(2);
   });
 
index b8c4774bec17f7500cc5541ac266a44178d17b62..f761d7e7b8f464d54068c5ac8842e3da2f03ce3a 100644 (file)
@@ -11,7 +11,6 @@ import { RgwRealmService } from '~/app/shared/api/rgw-realm.service';
 import { RgwZoneService } from '~/app/shared/api/rgw-zone.service';
 import { RgwZonegroupService } from '~/app/shared/api/rgw-zonegroup.service';
 import { RgwBucketService } from '~/app/shared/api/rgw-bucket.service';
-import { RgwUserService } from '~/app/shared/api/rgw-user.service';
 import { PrometheusService } from '~/app/shared/api/prometheus.service';
 
 import { RgwPromqls as queries } from '~/app/shared/enum/dashboard-promqls.enum';
@@ -46,7 +45,6 @@ export class RgwOverviewDashboardComponent implements OnInit, OnDestroy {
   multisiteInfo: object[] = [];
   ZonegroupSub: Subscription;
   ZoneSUb: Subscription;
-  UserSub: Subscription;
   HealthSub: Subscription;
   BucketSub: Subscription;
   queriesResults: any = {
@@ -78,7 +76,6 @@ export class RgwOverviewDashboardComponent implements OnInit, OnDestroy {
     private rgwZonegroupService: RgwZonegroupService,
     private rgwZoneService: RgwZoneService,
     private rgwBucketService: RgwBucketService,
-    private rgwUserService: RgwUserService,
     private prometheusService: PrometheusService,
     private rgwMultisiteService: RgwMultisiteService
   ) {
@@ -90,12 +87,6 @@ export class RgwOverviewDashboardComponent implements OnInit, OnDestroy {
       this.daemonSub = this.rgwDaemonService.list().subscribe((data: any) => {
         this.rgwDaemonCount = data.length;
       });
-      this.BucketSub = this.rgwBucketService.list().subscribe((data: any) => {
-        this.rgwBucketCount = data.length;
-      });
-      this.UserSub = this.rgwUserService.list().subscribe((data: any) => {
-        this.UserCount = data.length;
-      });
       this.HealthSub = this.healthService.getClusterCapacity().subscribe((data: any) => {
         this.objectCount = data['total_objects'];
         this.totalPoolUsedBytes = data['total_pool_bytes_used'];
@@ -103,6 +94,12 @@ export class RgwOverviewDashboardComponent implements OnInit, OnDestroy {
       });
       this.getSyncStatus();
     });
+    this.BucketSub = this.rgwBucketService
+      .getTotalBucketsAndUsersLength()
+      .subscribe((data: any) => {
+        this.rgwBucketCount = data['buckets_count'];
+        this.UserCount = data['users_count'];
+      });
     this.realmSub = this.rgwRealmService.list().subscribe((data: any) => {
       this.rgwRealmCount = data['realms'].length;
     });
@@ -143,7 +140,6 @@ export class RgwOverviewDashboardComponent implements OnInit, OnDestroy {
     this.ZonegroupSub.unsubscribe();
     this.ZoneSUb.unsubscribe();
     this.BucketSub.unsubscribe();
-    this.UserSub.unsubscribe();
     this.HealthSub.unsubscribe();
     if (this.timerGetPrometheusDataSub) {
       this.timerGetPrometheusDataSub.unsubscribe();
index 315c8b7560f1718f24091cc08e15b7bd86ec7bb7..7207d0b5ca72c88dd89102117239b6c0e1f27929 100644 (file)
@@ -43,6 +43,12 @@ export class RgwBucketService extends ApiClient {
     });
   }
 
+  getTotalBucketsAndUsersLength() {
+    return this.rgwDaemonService.request((params: HttpParams) => {
+      return this.http.get(`ui-${this.url}/buckets_and_users_count`, { params: params });
+    });
+  }
+
   create(
     bucket: string,
     uid: string,