From b658bb9c32ad31608921e77603003c004ab0f15b Mon Sep 17 00:00:00 2001 From: Pedro Gonzalez Gomez Date: Fri, 22 Mar 2024 15:20:48 +0100 Subject: [PATCH] mgr/dashboard: add system users to rgw user form Fixes: https://tracker.ceph.com/issues/65074 Signed-off-by: Pedro Gonzalez Gomez --- src/pybind/mgr/dashboard/controllers/rgw.py | 8 ++++++-- .../rgw-user-details.component.html | 4 ++-- .../rgw-user-details.component.spec.ts | 6 +++--- .../rgw-user-form/rgw-user-form.component.html | 16 ++++++++++++++++ .../rgw-user-form.component.spec.ts | 15 +++++++++++---- .../rgw/rgw-user-form/rgw-user-form.component.ts | 6 ++++-- src/pybind/mgr/dashboard/openapi.yaml | 4 ++++ 7 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/pybind/mgr/dashboard/controllers/rgw.py b/src/pybind/mgr/dashboard/controllers/rgw.py index 3238901c9fd42..4df642a9c7338 100644 --- a/src/pybind/mgr/dashboard/controllers/rgw.py +++ b/src/pybind/mgr/dashboard/controllers/rgw.py @@ -581,7 +581,7 @@ def get_emails(self, daemon_name=None): @allow_empty_body def create(self, uid, display_name, email=None, max_buckets=None, - suspended=None, generate_key=None, access_key=None, + system=None, suspended=None, generate_key=None, access_key=None, secret_key=None, daemon_name=None): params = {'uid': uid} if display_name is not None: @@ -590,6 +590,8 @@ def create(self, uid, display_name, email=None, max_buckets=None, params['email'] = email if max_buckets is not None: params['max-buckets'] = max_buckets + if system is not None: + params['system'] = system if suspended is not None: params['suspended'] = suspended if generate_key is not None: @@ -604,7 +606,7 @@ def create(self, uid, display_name, email=None, max_buckets=None, @allow_empty_body def set(self, uid, display_name=None, email=None, max_buckets=None, - suspended=None, daemon_name=None): + system=None, suspended=None, daemon_name=None): params = {'uid': uid} if display_name is not None: params['display-name'] = display_name @@ -612,6 +614,8 @@ def set(self, uid, display_name=None, email=None, max_buckets=None, params['email'] = email if max_buckets is not None: params['max-buckets'] = max_buckets + if system is not None: + params['system'] = system if suspended is not None: params['suspended'] = suspended result = self.proxy(daemon_name, 'POST', 'user', params) diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html index 27162404a62b3..49aff08e38757 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html @@ -60,8 +60,8 @@ System - {{ user.system === 'true' | booleanText }} + class="bold">System user + {{ user.system | booleanText }} { }); it('should show correct "System" info', () => { - component.selection = { uid: '', email: '', system: 'true', keys: [], swift_keys: [] }; + component.selection = { uid: '', email: '', system: true, keys: [], swift_keys: [] }; component.ngOnChanges(); fixture.detectChanges(); @@ -37,10 +37,10 @@ describe('RgwUserDetailsComponent', () => { const detailsTab = fixture.debugElement.nativeElement.querySelectorAll( '.table.table-striped.table-bordered tr td' ); - expect(detailsTab[10].textContent).toEqual('System'); + expect(detailsTab[10].textContent).toEqual('System user'); expect(detailsTab[11].textContent).toEqual('Yes'); - component.selection.system = 'false'; + component.selection.system = false; component.ngOnChanges(); fixture.detectChanges(); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html index 9fec45dfe01a8..69e9b4ca29baf 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.html @@ -164,6 +164,22 @@ + +
+
+
+ + + System users are distinct from regular users, they are used by the RGW service to perform administrative tasks, manage buckets and objects +
+
+
+
S3 key diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.spec.ts index 15665d53bb95b..64afa205e6926 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.spec.ts @@ -187,6 +187,7 @@ describe('RgwUserFormComponent', () => { max_buckets: -1, secret_key: '', suspended: false, + system: false, uid: null }); }); @@ -200,7 +201,8 @@ describe('RgwUserFormComponent', () => { display_name: null, email: null, max_buckets: -1, - suspended: false + suspended: false, + system: false }); }); @@ -216,6 +218,7 @@ describe('RgwUserFormComponent', () => { max_buckets: 0, secret_key: '', suspended: false, + system: false, uid: null }); }); @@ -229,7 +232,8 @@ describe('RgwUserFormComponent', () => { display_name: null, email: null, max_buckets: 0, - suspended: false + suspended: false, + system: false }); }); @@ -246,6 +250,7 @@ describe('RgwUserFormComponent', () => { max_buckets: 100, secret_key: '', suspended: false, + system: false, uid: null }); }); @@ -260,7 +265,8 @@ describe('RgwUserFormComponent', () => { display_name: null, email: null, max_buckets: 100, - suspended: false + suspended: false, + system: false }); }); }); @@ -283,7 +289,8 @@ describe('RgwUserFormComponent', () => { display_name: null, email: '', max_buckets: 1000, - suspended: false + suspended: false, + system: false }); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts index 9d4e1ce601b7f..b2cb7d6518d93 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts @@ -109,6 +109,7 @@ export class RgwUserFormComponent extends CdForm implements OnInit { 1000, [CdValidators.requiredIf({ max_buckets_mode: '1' }), CdValidators.number(false)] ], + system: [false], suspended: [false], // S3 key generate_key: [true], @@ -577,7 +578,7 @@ export class RgwUserFormComponent extends CdForm implements OnInit { * @return {Boolean} Returns TRUE if the general user settings have been modified. */ private _isGeneralDirty(): boolean { - return ['display_name', 'email', 'max_buckets_mode', 'max_buckets', 'suspended'].some( + return ['display_name', 'email', 'max_buckets_mode', 'max_buckets', 'system', 'suspended'].some( (path) => { return this.userForm.get(path).dirty; } @@ -624,6 +625,7 @@ export class RgwUserFormComponent extends CdForm implements OnInit { const result = { uid: this.getUID(), display_name: this.userForm.getValue('display_name'), + system: this.userForm.getValue('system'), suspended: this.userForm.getValue('suspended'), email: '', max_buckets: this.userForm.getValue('max_buckets'), @@ -658,7 +660,7 @@ export class RgwUserFormComponent extends CdForm implements OnInit { */ private _getUpdateArgs() { const result: Record = {}; - const keys = ['display_name', 'email', 'max_buckets', 'suspended']; + const keys = ['display_name', 'email', 'max_buckets', 'system', 'suspended']; for (const key of keys) { result[key] = this.userForm.getValue(key); } diff --git a/src/pybind/mgr/dashboard/openapi.yaml b/src/pybind/mgr/dashboard/openapi.yaml index 5244d4a983b26..9a14dcf2c0efe 100644 --- a/src/pybind/mgr/dashboard/openapi.yaml +++ b/src/pybind/mgr/dashboard/openapi.yaml @@ -11297,6 +11297,8 @@ paths: type: string suspended: type: string + system: + type: string uid: type: string required: @@ -11449,6 +11451,8 @@ paths: type: string suspended: type: string + system: + type: string type: object responses: '200':