]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Use admin ops API for rgw accounts 62027/head
authorNaman Munet <naman.munet@ibm.com>
Thu, 27 Feb 2025 08:14:54 +0000 (13:44 +0530)
committerNaman Munet <naman.munet@ibm.com>
Fri, 21 Mar 2025 08:51:16 +0000 (14:21 +0530)
Fixes: https://tracker.ceph.com/issues/69487
Signed-off-by: Naman Munet <naman.munet@ibm.com>
src/pybind/mgr/dashboard/controllers/rgw_iam.py
src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-user-accounts.service.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/api/rgw-user-accounts.service.ts
src/pybind/mgr/dashboard/openapi.yaml
src/pybind/mgr/dashboard/services/rgw_iam.py
src/pybind/mgr/dashboard/tests/test_rgw_iam.py

index d9a87dc56b81c3bb350cb8eb1a5af154e0bfe39e..3be4ffcee0282772d26966af3c85f8c3f5046fa4 100644 (file)
@@ -1,5 +1,6 @@
 from typing import Optional
 
+from ..controllers.rgw import RgwRESTController
 from ..security import Scope
 from ..services.rgw_iam import RgwAccounts
 from ..tools import str_to_bool
@@ -8,7 +9,7 @@ from . import APIDoc, APIRouter, EndpointDoc, RESTController, allow_empty_body
 
 @APIRouter('rgw/accounts', Scope.RGW)
 @APIDoc("RGW User Accounts API", "RgwUserAccounts")
-class RgwUserAccountsController(RESTController):
+class RgwUserAccountsController(RgwRESTController):
     @EndpointDoc("Update RGW account info",
                  parameters={'account_name': (str, 'Account name'),
                              'email': (str, 'Email'),
@@ -17,12 +18,13 @@ class RgwUserAccountsController(RESTController):
                              'max_users': (int, 'Max users'),
                              'max_roles': (int, 'Max roles'),
                              'max_group': (int, 'Max groups'),
-                             'max_access_keys': (int, 'Max access keys')})
+                             'max_access_keys': (int, 'Max access keys'),
+                             'daemon_name': (str, 'Name of the daemon')})
     @allow_empty_body
     def create(self, account_name: str, tenant: Optional[str] = None,
                email: Optional[str] = None, max_buckets: Optional[int] = None,
                max_users: Optional[int] = None, max_roles: Optional[int] = None,
-               max_group: Optional[int] = None,
+               max_group: Optional[int] = None, daemon_name=None,
                max_access_keys: Optional[int] = None):
         """
         Create an account
@@ -31,11 +33,26 @@ class RgwUserAccountsController(RESTController):
         :return: Returns account resource.
         :rtype: Dict[str, Any]
         """
-        return RgwAccounts.create_account(account_name, tenant, email,
-                                          max_buckets, max_users, max_roles,
-                                          max_group, max_access_keys)
+        params = {'name': account_name}
+        if tenant:
+            params['tenant'] = tenant
+        if email:
+            params['email'] = email
+        if max_buckets:
+            params['max-buckets'] = str(max_buckets)
+        if max_users:
+            params['max-users'] = str(max_users)
+        if max_roles:
+            params['max-roles'] = str(max_roles)
+        if max_group:
+            params['max-group'] = str(max_group)
+        if max_access_keys:
+            params['max-access-keys'] = str(max_access_keys)
 
-    def list(self, detailed: bool = False):
+        result = self.proxy(daemon_name, 'POST', 'account', params)
+        return result
+
+    def list(self, daemon_name=None, detailed: bool = False):
         """
         List all account ids or all detailed account info based on the 'detailed' query parameter.
 
@@ -43,26 +60,37 @@ class RgwUserAccountsController(RESTController):
         - If detailed=False, returns only account ids.
         """
         detailed = str_to_bool(detailed)
-        return RgwAccounts.get_accounts(detailed)
+        account_list = RgwAccounts.get_accounts()
+        detailed_account_list = []
+        if detailed:
+            for account in account_list:
+                detailed_account_list.append(self.get_account(account, daemon_name))
+            return detailed_account_list
+        return account_list
 
     @EndpointDoc("Get RGW Account by id",
-                 parameters={'account_id': (str, 'Account id')})
-    def get(self, account_id: str):
+                 parameters={'account_id': (str, 'Account id'),
+                             'daemon_name': (str, 'Name of the daemon')})
+    def get(self, account_id: str, daemon_name=None):
         """
         Get an account by account id
         """
-        return RgwAccounts.get_account(account_id)
+        return self.get_account(account_id, daemon_name)
+
+    def get_account(self, account_id, daemon_name=None) -> dict:
+        return self.proxy(daemon_name, 'GET', 'account', {'id': account_id})
 
     @EndpointDoc("Delete RGW Account",
-                 parameters={'account_id': (str, 'Account id')})
-    def delete(self, account_id):
+                 parameters={'account_id': (str, 'Account id'),
+                             'daemon_name': (str, 'Name of the daemon')})
+    def delete(self, account_id, daemon_name=None):
         """
         Removes an account
 
         :param account_id: account identifier
         :return: None.
         """
-        return RgwAccounts.delete_account(account_id)
+        return self.proxy(daemon_name, 'DELETE', 'account', {'id': account_id}, json_response=False)
 
     @EndpointDoc("Update RGW account info",
                  parameters={'account_id': (str, 'Account id'),
@@ -73,13 +101,14 @@ class RgwUserAccountsController(RESTController):
                              'max_users': (int, 'Max users'),
                              'max_roles': (int, 'Max roles'),
                              'max_group': (int, 'Max groups'),
-                             'max_access_keys': (int, 'Max access keys')})
+                             'max_access_keys': (int, 'Max access keys'),
+                             'daemon_name': (str, 'Name of the daemon')})
     @allow_empty_body
     def set(self, account_id: str, account_name: str,
             email: Optional[str] = None, tenant: Optional[str] = None,
             max_buckets: Optional[int] = None, max_users: Optional[int] = None,
             max_roles: Optional[int] = None, max_group: Optional[int] = None,
-            max_access_keys: Optional[int] = None):
+            max_access_keys: Optional[int] = None, daemon_name=None):
         """
         Modifies an account
 
@@ -87,9 +116,26 @@ class RgwUserAccountsController(RESTController):
         :return: Returns modified account resource.
         :rtype: Dict[str, Any]
         """
-        return RgwAccounts.modify_account(account_id, account_name, email, tenant,
-                                          max_buckets, max_users, max_roles,
-                                          max_group, max_access_keys)
+
+        params = {'id': account_id}
+        if account_name:
+            params['name'] = account_name
+        if tenant:
+            params['tenant'] = tenant
+        if email:
+            params['email'] = email
+        if max_buckets:
+            params['max-buckets'] = str(max_buckets)
+        if max_users:
+            params['max-users'] = str(max_users)
+        if max_roles:
+            params['max-roles'] = str(max_roles)
+        if max_group:
+            params['max-group'] = str(max_group)
+        if max_access_keys:
+            params['max-access-keys'] = str(max_access_keys)
+
+        return self.proxy(daemon_name, 'PUT', 'account', params)
 
     @EndpointDoc("Set RGW Account/Bucket quota",
                  parameters={'account_id': (str, 'Account id'),
index 8a3fd3f01201519063e99ac0cff5aadb8226f8b9..40d146b41b8f6d7eb06372b3d439d63fed5cabf6 100644 (file)
@@ -3,6 +3,7 @@ import { TestBed } from '@angular/core/testing';
 import { RgwUserAccountsService } from './rgw-user-accounts.service';
 import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
 import { Account } from '~/app/ceph/rgw/models/rgw-user-accounts';
+import { RgwHelper } from '~/testing/unit-test-helper';
 
 const mockAccountData: Account[] = [
   {
@@ -68,6 +69,7 @@ describe('RgwUserAccountsService', () => {
     });
     service = TestBed.inject(RgwUserAccountsService);
     httpTesting = TestBed.inject(HttpTestingController);
+    RgwHelper.selectDaemon();
   });
 
   it('should be created', () => {
@@ -76,8 +78,56 @@ describe('RgwUserAccountsService', () => {
 
   it('should fetch detailed list of accounts', () => {
     service.list(true).subscribe();
-    const req = httpTesting.expectOne('api/rgw/accounts?detailed=true');
+    const req = httpTesting.expectOne(
+      `api/rgw/accounts?${RgwHelper.DAEMON_QUERY_PARAM}&detailed=true`
+    );
     expect(req.request.method).toBe('GET');
     req.flush(mockAccountData);
   });
+
+  it('should fetch single account detail', () => {
+    service.get('RGW80617806988089685').subscribe();
+    const req = httpTesting.expectOne(
+      `api/rgw/accounts/get?${RgwHelper.DAEMON_QUERY_PARAM}&account_id=RGW80617806988089685`
+    );
+    expect(req.request.method).toBe('GET');
+    req.flush(mockAccountData[0]);
+  });
+
+  it('should call create method', () => {
+    service.create(mockAccountData[0]).subscribe();
+    const req = httpTesting.expectOne(`api/rgw/accounts?${RgwHelper.DAEMON_QUERY_PARAM}`);
+    expect(req.request.method).toBe('POST');
+    req.flush(mockAccountData[0]);
+  });
+
+  it('should call modify method', () => {
+    service.modify(mockAccountData[0]).subscribe();
+    const req = httpTesting.expectOne(`api/rgw/accounts/set?${RgwHelper.DAEMON_QUERY_PARAM}`);
+    expect(req.request.method).toBe('PUT');
+    req.flush(mockAccountData[0]);
+  });
+
+  it('should call remove method', () => {
+    service.remove('RGW12444466134482748').subscribe();
+    const req = httpTesting.expectOne(
+      `api/rgw/accounts/RGW12444466134482748?${RgwHelper.DAEMON_QUERY_PARAM}`
+    );
+    expect(req.request.method).toBe('DELETE');
+    req.flush(null);
+  });
+
+  it('should call setQuota method', () => {
+    service
+      .setQuota('RGW12444466134482748', {
+        quota_type: 'bucket',
+        max_size: '10MB',
+        max_objects: '1000',
+        enabled: true
+      })
+      .subscribe();
+    const req = httpTesting.expectOne(`api/rgw/accounts/RGW12444466134482748/quota`);
+    expect(req.request.method).toBe('PUT');
+    req.flush(null);
+  });
 });
index bd407357c61204e61f2cd61d347ce888896e7188..b5035fd344a6df76874d57132faab4765c403a5a 100644 (file)
@@ -1,6 +1,8 @@
 import { HttpClient, HttpParams } from '@angular/common/http';
 import { Injectable } from '@angular/core';
 import { Observable } from 'rxjs';
+import { RgwDaemonService } from './rgw-daemon.service';
+import { Account } from '~/app/ceph/rgw/models/rgw-user-accounts';
 
 @Injectable({
   providedIn: 'root'
@@ -8,34 +10,42 @@ import { Observable } from 'rxjs';
 export class RgwUserAccountsService {
   private url = 'api/rgw/accounts';
 
-  constructor(private http: HttpClient) {}
+  constructor(private http: HttpClient, private rgwDaemonService: RgwDaemonService) {}
 
   list(detailed?: boolean): Observable<any> {
-    let params = new HttpParams();
-    if (detailed) {
-      params = params.append('detailed', detailed);
-    }
-    return this.http.get(this.url, { params });
+    return this.rgwDaemonService.request((params: HttpParams) => {
+      if (detailed) {
+        params = params.append('detailed', detailed);
+      }
+      return this.http.get(this.url, { params });
+    });
   }
 
   get(account_id: string): Observable<any> {
-    let params = new HttpParams();
-    if (account_id) {
-      params = params.append('account_id', account_id);
-    }
-    return this.http.get(`${this.url}/get`, { params });
+    return this.rgwDaemonService.request((params: HttpParams) => {
+      if (account_id) {
+        params = params.append('account_id', account_id);
+      }
+      return this.http.get(`${this.url}/get`, { params });
+    });
   }
 
-  create(payload: any): Observable<any> {
-    return this.http.post(this.url, payload);
+  create(payload: Partial<Account>): Observable<any> {
+    return this.rgwDaemonService.request((params: HttpParams) => {
+      return this.http.post(this.url, payload, { params: params });
+    });
   }
 
-  modify(payload: any): Observable<any> {
-    return this.http.put(`${this.url}/set`, payload);
+  modify(payload: Partial<Account>): Observable<any> {
+    return this.rgwDaemonService.request((params: HttpParams) => {
+      return this.http.put(`${this.url}/set`, payload, { params: params });
+    });
   }
 
   remove(accountId: string) {
-    return this.http.delete(`${this.url}/${accountId}`);
+    return this.rgwDaemonService.request((params: HttpParams) => {
+      return this.http.delete(`${this.url}/${accountId}`, { params: params });
+    });
   }
 
   setQuota(
index e1e5fab12dfa14c903aece231e85f1a463ccce96..5ea9e10d9fa731ac71e064bbd1695b015dd76448 100755 (executable)
@@ -11040,6 +11040,11 @@ paths:
         \ detailed account info.\n        - If detailed=False, returns only account\
         \ ids.\n        "
       parameters:
+      - allowEmptyValue: true
+        in: query
+        name: daemon_name
+        schema:
+          type: string
       - default: false
         in: query
         name: detailed
@@ -11077,6 +11082,9 @@ paths:
                 account_name:
                   description: Account name
                   type: string
+                daemon_name:
+                  description: Name of the daemon
+                  type: string
                 email:
                   description: Email
                   type: string
@@ -11137,6 +11145,12 @@ paths:
         required: true
         schema:
           type: string
+      - allowEmptyValue: true
+        description: Name of the daemon
+        in: query
+        name: daemon_name
+        schema:
+          type: string
       responses:
         '202':
           content:
@@ -11171,6 +11185,12 @@ paths:
         required: true
         schema:
           type: string
+      - allowEmptyValue: true
+        description: Name of the daemon
+        in: query
+        name: daemon_name
+        schema:
+          type: string
       responses:
         '200':
           content:
@@ -11210,6 +11230,9 @@ paths:
                 account_name:
                   description: Account name
                   type: string
+                daemon_name:
+                  description: Name of the daemon
+                  type: string
                 email:
                   description: Email
                   type: string
index 88730dd96a1d6ac495f1b83ce378db3b9cda1ffa..31cefd3a026cac4e4f719bfed384ac383fb75a15 100644 (file)
@@ -1,5 +1,5 @@
 from subprocess import SubprocessError
-from typing import List, Optional
+from typing import List
 
 from .. import mgr
 from ..exceptions import DashboardException
@@ -21,66 +21,9 @@ class RgwAccounts:
             raise DashboardException(e, component='rgw')
 
     @classmethod
-    def get_accounts(cls, detailed: bool = False):
-        """
-        Query account Id's, optionally returning full details.
-
-        :param detailed: Boolean to indicate if full account details are required.
-        """
+    def get_accounts(cls):
         get_accounts_cmd = ['account', 'list']
-        account_list = cls.send_rgw_cmd(get_accounts_cmd)
-        detailed_account_list = []
-        if detailed:
-            for account in account_list:
-                detailed_account_list.append(cls.get_account(account))
-            return detailed_account_list
-        return account_list
-
-    @classmethod
-    def get_account(cls, account_id: str):
-        get_account_cmd = ['account', 'get', '--account-id', account_id]
-        return cls.send_rgw_cmd(get_account_cmd)
-
-    @classmethod
-    def create_account(cls, account_name: str, tenant: Optional[str] = None,
-                       email: Optional[str] = None, max_buckets: Optional[int] = None,
-                       max_users: Optional[int] = None, max_roles: Optional[int] = None,
-                       max_group: Optional[int] = None, max_access_keys: Optional[int] = None):
-        create_accounts_cmd = ['account', 'create']
-
-        create_accounts_cmd += cls.get_common_args_list(account_name, email,
-                                                        tenant, max_buckets,
-                                                        max_users, max_roles,
-                                                        max_group, max_access_keys)
-
-        return cls.send_rgw_cmd(create_accounts_cmd)
-
-    @classmethod
-    def modify_account(cls, account_id: str, account_name: str,
-                       email: Optional[str] = None, tenant: Optional[str] = None,
-                       max_buckets: Optional[int] = None, max_users: Optional[int] = None,
-                       max_roles: Optional[int] = None, max_group: Optional[int] = None,
-                       max_access_keys: Optional[int] = None):
-        modify_accounts_cmd = ['account', 'modify', '--account-id', account_id]
-
-        modify_accounts_cmd += cls.get_common_args_list(account_name, email,
-                                                        tenant, max_buckets,
-                                                        max_users, max_roles,
-                                                        max_group, max_access_keys)
-
-        return cls.send_rgw_cmd(modify_accounts_cmd)
-
-    @classmethod
-    def delete_account(cls, account_id: str):
-        modify_accounts_cmd = ['account', 'rm', '--account-id', account_id]
-
-        return cls.send_rgw_cmd(modify_accounts_cmd)
-
-    @classmethod
-    def get_account_stats(cls, account_id: str):
-        account_stats_cmd = ['account', 'stats', '--account-id', account_id]
-
-        return cls.send_rgw_cmd(account_stats_cmd)
+        return cls.send_rgw_cmd(get_accounts_cmd)
 
     @classmethod
     def set_quota(cls, quota_type: str, account_id: str, max_size: str, max_objects: str,
@@ -99,36 +42,3 @@ class RgwAccounts:
                                 '--account-id', account_id]
 
         return cls.send_rgw_cmd(set_quota_status_cmd)
-
-    @classmethod
-    def get_common_args_list(cls, account_name: str, email: Optional[str] = None,
-                             tenant: Optional[str] = None, max_buckets: Optional[int] = None,
-                             max_users: Optional[int] = None, max_roles: Optional[int] = None,
-                             max_group: Optional[int] = None,
-                             max_access_keys: Optional[int] = None):
-        common_cmd_list = []
-        if account_name:
-            common_cmd_list += ['--account-name', account_name]
-
-        if email:
-            common_cmd_list += ['--email', email]
-
-        if tenant:
-            common_cmd_list += ['--tenant', tenant]
-
-        if max_buckets:
-            common_cmd_list += ['--max_buckets', str(max_buckets)]
-
-        if max_users:
-            common_cmd_list += ['--max_users', str(max_users)]
-
-        if max_roles:
-            common_cmd_list += ['--max_roles', str(max_roles)]
-
-        if max_group:
-            common_cmd_list += ['--max_groups', str(max_group)]
-
-        if max_access_keys:
-            common_cmd_list += ['--max_access_keys', str(max_access_keys)]
-
-        return common_cmd_list
index 90bb9ac16c872ae34fc1369c184b519ad35a7e54..567021910251fdb1b703338eab3687c02278c0cf 100644 (file)
@@ -1,16 +1,21 @@
-from unittest import TestCase
-from unittest.mock import patch
+from unittest.mock import call, patch
 
 from ..controllers.rgw_iam import RgwUserAccountsController
-from ..services.rgw_iam import RgwAccounts
+from ..tests import ControllerTestCase
 
 
-class TestRgwUserAccountsController(TestCase):
+class TestRgwUserAccountsController(ControllerTestCase):
+    @classmethod
+    def setup_server(cls):
+        cls.setup_controllers([RgwUserAccountsController], '/test')
 
-    @patch.object(RgwAccounts, 'create_account')
-    def test_create_account(self, mock_create_account):
-        mockReturnVal = {
-            "id": "RGW18661471562806836",
+    @patch('dashboard.controllers.rgw.RgwAccounts.get_accounts')
+    @patch('dashboard.controllers.rgw_iam.RgwUserAccountsController.get_account')
+    @patch('dashboard.controllers.rgw_iam.RgwUserAccountsController.proxy')
+    def test_account_list(self, mock_proxy, mock_get_account, mock_get_accounts):
+        mock_get_accounts.return_value = ['RGW67392003738907404']
+        mock_proxy.return_value = {
+            "id": "RGW67392003738907404",
             "tenant": "",
             "name": "",
             "email": "",
@@ -35,71 +40,46 @@ class TestRgwUserAccountsController(TestCase):
             "max_access_keys": 4
         }
 
-        # Mock the return value of the create_account method
-        mock_create_account.return_value = mockReturnVal
-
-        controller = RgwUserAccountsController()
-        result = controller.create(account_name='test_account', tenant='',
-                                   email='test@example.com', max_buckets=1000,
-                                   max_users=1000, max_roles=1000, max_group=1000,
-                                   max_access_keys=4)
-
-        # Check if the account creation method was called with the correct parameters
-        mock_create_account.assert_called_with('test_account', '', 'test@example.com',
-                                               1000, 1000, 1000, 1000, 4)
-        # Check the returned result
-        self.assertEqual(result, mockReturnVal)
-
-    @patch.object(RgwAccounts, 'get_accounts')
-    def test_list_accounts(self, mock_get_accounts):
-        mock_return_value = [
-            "RGW22222222222222222",
-            "RGW59378973811515857",
-            "RGW11111111111111111"
-        ]
-
-        mock_get_accounts.return_value = mock_return_value
-
-        controller = RgwUserAccountsController()
-        result = controller.list(detailed=False)
+        mock_get_account.side_effect = lambda account_id, daemon_name=None: {
+            "id": account_id,
+            "tenant": "",
+            "name": "",
+            "email": "",
+            "quota": {
+                "enabled": False,
+                "check_on_raw": False,
+                "max_size": -1,
+                "max_size_kb": 0,
+                "max_objects": -1
+            },
+            "bucket_quota": {
+                "enabled": False,
+                "check_on_raw": False,
+                "max_size": -1,
+                "max_size_kb": 0,
+                "max_objects": -1
+            },
+            "max_users": 1000,
+            "max_roles": 1000,
+            "max_groups": 1000,
+            "max_buckets": 1000,
+            "max_access_keys": 4
+        }
+        self._get('/test/api/rgw/accounts?daemon_name=dummy-daemon')
+        self.assertStatus(200)
+        self.assertJsonBody(['RGW67392003738907404'])
 
-        mock_get_accounts.assert_called_with(False)
+        mock_get_accounts.assert_called_once()
 
-        self.assertEqual(result, mock_return_value)
+        self._get('/test/api/rgw/accounts?daemon_name=dummy-daemon&detailed=true')
+        self.assertStatus(200)
 
-    @patch.object(RgwAccounts, 'get_accounts')
-    def test_list_accounts_with_details(self, mock_get_accounts):
-        mock_return_value = [
+        expected_detailed_response = [
             {
-                "id": "RGW22222222222222222",
+                "id": "RGW67392003738907404",
                 "tenant": "",
-                "name": "Account2",
-                "email": "account2@ceph.com",
-                "quota": {
-                    "enabled": False,
-                    "check_on_raw": False,
-                    "max_size": -1,
-                    "max_size_kb": 0,
-                    "max_objects": -1
-                },
-                "bucket_quota": {
-                    "enabled": False,
-                    "check_on_raw": False,
-                    "max_size": -1,
-                    "max_size_kb": 0,
-                    "max_objects": -1
-                },
-                "max_users": 1000,
-                "max_roles": 1000,
-                "max_groups": 1000,
-                "max_buckets": 1000,
-                "max_access_keys": 4
-            },
-            {
-                "id": "RGW11111111111111111",
-                "tenant": "",
-                "name": "Account1",
-                "email": "account1@ceph.com",
+                "name": "",
+                "email": "",
                 "quota": {
                     "enabled": False,
                     "check_on_raw": False,
@@ -121,23 +101,22 @@ class TestRgwUserAccountsController(TestCase):
                 "max_access_keys": 4
             }
         ]
+        self.assertJsonBody(expected_detailed_response)
 
-        mock_get_accounts.return_value = mock_return_value
-
-        controller = RgwUserAccountsController()
-        result = controller.list(detailed=True)
+        mock_get_account.assert_has_calls([
+            call('RGW67392003738907404', 'dummy-daemon')
+        ])
 
-        mock_get_accounts.assert_called_with(True)
+        self._get('/test/api/rgw/accounts/RGW67392003738907404?daemon_name=dummy-daemon')
+        self.assertStatus(200)
 
-        self.assertEqual(result, mock_return_value)
-
-    @patch.object(RgwAccounts, 'get_account')
-    def test_get_account(self, mock_get_account):
-        mock_return_value = {
-            "id": "RGW22222222222222222",
+    @patch('dashboard.controllers.rgw_iam.RgwUserAccountsController.proxy')
+    def test_create_account(self, mock_proxy):
+        mock_proxy.return_value = {
+            "id": "RGW67392003738907404",
             "tenant": "",
-            "name": "Account2",
-            "email": "account2@ceph.com",
+            "name": "jack",
+            "email": "",
             "quota": {
                 "enabled": False,
                 "check_on_raw": False,
@@ -158,33 +137,60 @@ class TestRgwUserAccountsController(TestCase):
             "max_buckets": 1000,
             "max_access_keys": 4
         }
-        mock_get_account.return_value = mock_return_value
-
-        controller = RgwUserAccountsController()
-        result = controller.get(account_id='RGW22222222222222222')
-
-        mock_get_account.assert_called_with('RGW22222222222222222')
 
-        self.assertEqual(result, mock_return_value)
-
-    @patch.object(RgwAccounts, 'delete_account')
-    def test_delete_account(self, mock_delete_account):
-        mock_delete_account.return_value = None
-
-        controller = RgwUserAccountsController()
-        result = controller.delete(account_id='RGW59378973811515857')
-
-        mock_delete_account.assert_called_with('RGW59378973811515857')
-
-        self.assertEqual(result, None)
+        self._post('/test/api/rgw/accounts?daemon_name=dummy-daemon', data={
+            'account_name': 'jack',
+            'max_buckets': '1000',
+            'max_users': '1000',
+            'max_roles': '1000',
+            'max_group': '1000',
+            'max_access_keys': '4'
+        })
+
+        mock_proxy.assert_called_once_with(
+            'dummy-daemon', 'POST', 'account', {
+                'name': 'jack',
+                'max-buckets': '1000',
+                'max-users': '1000',
+                'max-roles': '1000',
+                'max-group': '1000',
+                'max-access-keys': '4'
+            })
+
+    @patch('dashboard.controllers.rgw_iam.RgwUserAccountsController.get_account')
+    @patch('dashboard.controllers.rgw_iam.RgwUserAccountsController.proxy')
+    def test_get_account(self, mock_get_account, mock_proxy):
+        mock_proxy.return_value = {
+            "id": "RGW67392003738907404",
+            "tenant": "",
+            "name": "",
+            "email": "",
+            "quota": {
+                "enabled": False,
+                "check_on_raw": False,
+                "max_size": -1,
+                "max_size_kb": 0,
+                "max_objects": -1
+            },
+            "bucket_quota": {
+                "enabled": False,
+                "check_on_raw": False,
+                "max_size": -1,
+                "max_size_kb": 0,
+                "max_objects": -1
+            },
+            "max_users": 1000,
+            "max_roles": 1000,
+            "max_groups": 1000,
+            "max_buckets": 1000,
+            "max_access_keys": 4
+        }
 
-    @patch.object(RgwAccounts, 'modify_account')
-    def test_set_account_name(self, mock_modify_account):
-        mock_return_value = mock_return_value = {
-            "id": "RGW59378973811515857",
+        mock_get_account.side_effect = lambda account_id, daemon_name=None: {
+            "id": account_id,
             "tenant": "",
-            "name": "new_account_name",
-            "email": "new_email@example.com",
+            "name": "",
+            "email": "",
             "quota": {
                 "enabled": False,
                 "check_on_raw": False,
@@ -205,20 +211,65 @@ class TestRgwUserAccountsController(TestCase):
             "max_buckets": 1000,
             "max_access_keys": 4
         }
-        mock_modify_account.return_value = mock_return_value
+        self._get('/test/api/rgw/accounts/RGW67392003738907404?daemon_name=dummy-daemon')
+        self.assertStatus(200)
 
-        controller = RgwUserAccountsController()
-        result = controller.set(account_id='RGW59378973811515857', account_name='new_account_name',
-                                email='new_email@example.com', tenant='', max_buckets=1000,
-                                max_users=1000, max_roles=1000, max_group=1000, max_access_keys=4)
+    @patch('dashboard.controllers.rgw_iam.RgwUserAccountsController.proxy')
+    def test_delete_account(self, mock_proxy):
+        mock_proxy.return_value = None
 
-        mock_modify_account.assert_called_with('RGW59378973811515857', 'new_account_name',
-                                               'new_email@example.com', '', 1000, 1000, 1000,
-                                               1000, 4)
+        self._delete('/test/api/rgw/accounts/RGW67392003738907404?daemon_name=dummy-daemon')
+        self.assertStatus(204)
 
-        self.assertEqual(result, mock_return_value)
+    @patch('dashboard.controllers.rgw_iam.RgwUserAccountsController.proxy')
+    def test_set_account(self, mock_proxy):
+        mock_proxy.return_value = {
+            "id": "RGW67392003738907404",
+            "tenant": "",
+            "name": "jack",
+            "email": "",
+            "quota": {
+                "enabled": False,
+                "check_on_raw": False,
+                "max_size": -1,
+                "max_size_kb": 0,
+                "max_objects": -1
+            },
+            "bucket_quota": {
+                "enabled": False,
+                "check_on_raw": False,
+                "max_size": -1,
+                "max_size_kb": 0,
+                "max_objects": -1
+            },
+            "max_users": 1000,
+            "max_roles": 1000,
+            "max_groups": 1000,
+            "max_buckets": 1000,
+            "max_access_keys": 4
+        }
 
-    @patch.object(RgwAccounts, 'set_quota')
+        self._put('/test/api/rgw/accounts/RGW67392003738907404?daemon_name=dummy-daemon', data={
+            'account_name': 'jack',
+            'max_buckets': '1000',
+            'max_users': '1000',
+            'max_roles': '1000',
+            'max_group': '1000',
+            'max_access_keys': '4'
+        })
+
+        mock_proxy.assert_called_once_with(
+            'dummy-daemon', 'PUT', 'account', {
+                'id': 'RGW67392003738907404',
+                'name': 'jack',
+                'max-buckets': '1000',
+                'max-users': '1000',
+                'max-roles': '1000',
+                'max-group': '1000',
+                'max-access-keys': '4'
+            })
+
+    @patch('dashboard.controllers.rgw_iam.RgwUserAccountsController.set_quota')
     def test_set_quota(self, mock_set_quota):
         mock_return_value = {
             "id": "RGW11111111111111111",
@@ -249,14 +300,13 @@ class TestRgwUserAccountsController(TestCase):
         mock_set_quota.return_value = mock_return_value
 
         controller = RgwUserAccountsController()
-        result = controller.set_quota(quota_type='account', account_id='RGW11111111111111111',
-                                      max_size='10GB', max_objects='1000', enabled=True)
+        result = controller.set_quota('account', 'RGW11111111111111111', '10GB', '1000', True)
 
         mock_set_quota.assert_called_with('account', 'RGW11111111111111111', '10GB', '1000', True)
 
         self.assertEqual(result, mock_return_value)
 
-    @patch.object(RgwAccounts, 'set_quota_status')
+    @patch('dashboard.controllers.rgw_iam.RgwUserAccountsController.set_quota_status')
     def test_set_quota_status(self, mock_set_quota_status):
         mock_return_value = {
             "id": "RGW11111111111111111",
@@ -287,9 +337,7 @@ class TestRgwUserAccountsController(TestCase):
         mock_set_quota_status.return_value = mock_return_value
 
         controller = RgwUserAccountsController()
-        result = controller.set_quota_status(quota_type='account',
-                                             account_id='RGW11111111111111111',
-                                             quota_status='enabled')
+        result = controller.set_quota_status('account', 'RGW11111111111111111', 'enabled')
 
         mock_set_quota_status.assert_called_with('account', 'RGW11111111111111111', 'enabled')