Skip to content

Commit b48556d

Browse files
authored
Merge pull request ceph#61315 from rhcs-dashboard/smb-join_auth-usersgroups-form-actions
mgr/dashboard: add actions for smb join-auth and usersgroups resources mgmt also updates smb cluster form Reviewed-by: Afreen Misbah <[email protected]>
2 parents 6020de3 + 10af905 commit b48556d

32 files changed

+2194
-273
lines changed

src/pybind/mgr/dashboard/controllers/smb.py

Lines changed: 130 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11

22
# -*- coding: utf-8 -*-
3-
43
import json
54
import logging
65
from functools import wraps
76
from typing import List
87

98
from smb.enums import Intent
109
from smb.proto import Simplified
11-
from smb.resources import Cluster, Share
10+
from smb.resources import Cluster, JoinAuth, Share, UsersAndGroups
1211

1312
from dashboard.controllers._docs import EndpointDoc
1413
from dashboard.controllers._permissions import CreatePermission, DeletePermission
@@ -42,35 +41,6 @@
4241
}, "Placement configuration for the resource")
4342
}
4443

45-
CLUSTER_SCHEMA_RESULTS = {
46-
"results": ([{
47-
"resource": ({
48-
"resource_type": (str, "ceph.smb.cluster"),
49-
"cluster_id": (str, "Unique identifier for the cluster"),
50-
"auth_mode": (str, "Either 'active-directory' or 'user'"),
51-
"intent": (str, "Desired state of the resource, e.g., 'present' or 'removed'"),
52-
"domain_settings": ({
53-
"realm": (str, "Domain realm, e.g., 'DOMAIN1.SINK.TEST'"),
54-
"join_sources": ([{
55-
"source_type": (str, "resource"),
56-
"ref": (str, "Reference identifier for the join auth resource")
57-
}], "List of join auth sources for domain settings")
58-
}, "Domain-specific settings for active-directory auth mode"),
59-
"user_group_settings": ([{
60-
"source_type": (str, "resource"),
61-
"ref": (str, "Reference identifier for the user group resource")
62-
}], "User group settings for user auth mode (optional)"),
63-
"custom_dns": ([str], "List of custom DNS server addresses (optional)"),
64-
"placement": ({
65-
"count": (int, "Number of instances to place")
66-
}, "Placement configuration for the resource (optional)"),
67-
}, "Resource details"),
68-
"state": (str, "State of the resource"),
69-
"success": (bool, "Indicates whether the operation was successful")
70-
}], "List of results with resource details"),
71-
"success": (bool, "Overall success status of the operation")
72-
}
73-
7444
LIST_CLUSTER_SCHEMA = [CLUSTER_SCHEMA]
7545

7646
SHARE_SCHEMA = {
@@ -125,29 +95,26 @@
12595

12696
LIST_USERSGROUPS_SCHEMA = [USERSGROUPS_SCHEMA]
12797

128-
SHARE_SCHEMA_RESULTS = {
129-
"results": ([{
130-
"resource": ({
131-
"resource_type": (str, "ceph.smb.share"),
132-
"cluster_id": (str, "Unique identifier for the cluster"),
133-
"share_id": (str, "Unique identifier for the share"),
134-
"intent": (str, "Desired state of the resource, e.g., 'present' or 'removed'"),
135-
"name": (str, "Name of the share"),
136-
"readonly": (bool, "Indicates if the share is read-only"),
137-
"browseable": (bool, "Indicates if the share is browseable"),
138-
"cephfs": ({
139-
"volume": (str, "Name of the CephFS file system"),
140-
"path": (str, "Path within the CephFS file system"),
141-
"subvolumegroup": (str, "Subvolume Group in CephFS file system"),
142-
"subvolume": (str, "Subvolume within the CephFS file system"),
143-
"provider": (str, "Provider of the CephFS share, e.g., 'samba-vfs'")
144-
}, "Configuration for the CephFS share")
145-
}, "Resource details"),
146-
"state": (str, "State of the resource"),
147-
"success": (bool, "Indicates whether the operation was successful")
148-
}], "List of results with resource details"),
149-
"success": (bool, "Overall success status of the operation")
150-
}
98+
99+
def add_results_to_schema(schema):
100+
101+
results_field = {
102+
"results": ([{
103+
"resource": (schema, "Resource"),
104+
"state": (str, "The current state of the resource,\
105+
e.g., 'created', 'updated', 'deleted'"),
106+
"success": (bool, "Indicates if the operation was successful"),
107+
}], "List of operation results"),
108+
"success": (bool, "Indicates if the overall operation was successful")
109+
}
110+
111+
return results_field
112+
113+
114+
CLUSTER_SCHEMA_RESULTS = add_results_to_schema(CLUSTER_SCHEMA)
115+
SHARE_SCHEMA_RESULTS = add_results_to_schema(SHARE_SCHEMA)
116+
JOIN_AUTH_SCHEMA_RESULTS = add_results_to_schema(JOIN_AUTH_SCHEMA)
117+
USERSGROUPS_SCHEMA_RESULTS = add_results_to_schema(JOIN_AUTH_SCHEMA_RESULTS)
151118

152119

153120
def raise_on_failure(func):
@@ -319,7 +286,7 @@ class SMBJoinAuth(RESTController):
319286
@ReadPermission
320287
@EndpointDoc("List smb join authorization resources",
321288
responses={200: LIST_JOIN_AUTH_SCHEMA})
322-
def list(self, join_auth: str = '') -> List[Share]:
289+
def list(self) -> List[JoinAuth]:
323290
"""
324291
List all smb join auth resources
325292
@@ -329,9 +296,61 @@ def list(self, join_auth: str = '') -> List[Share]:
329296
res = mgr.remote(
330297
'smb',
331298
'show',
332-
[f'{self._resource}.{join_auth}' if join_auth else self._resource])
299+
[self._resource])
333300
return res['resources'] if 'resources' in res else [res]
334301

302+
@ReadPermission
303+
@EndpointDoc("Get smb join authorization resource",
304+
responses={200: JOIN_AUTH_SCHEMA})
305+
def get(self, auth_id: str) -> JoinAuth:
306+
"""
307+
Get Join auth resource
308+
309+
:return: Returns join auth.
310+
:rtype: Dict
311+
"""
312+
res = mgr.remote(
313+
'smb',
314+
'show',
315+
[f'{self._resource}.{auth_id}'])
316+
return res['resources'] if 'resources' in res else res
317+
318+
@CreatePermission
319+
@EndpointDoc("Create smb join auth",
320+
parameters={
321+
'auth_id': (str, 'auth_id'),
322+
'username': (str, 'username'),
323+
'password': (str, 'password')
324+
},
325+
responses={201: JOIN_AUTH_SCHEMA_RESULTS})
326+
def create(self, join_auth: JoinAuth) -> Simplified:
327+
"""
328+
Create smb join auth resource
329+
330+
:return: Returns join auth resource.
331+
:rtype: Dict
332+
"""
333+
return mgr.remote('smb', 'apply_resources', json.dumps(join_auth)).to_simplified()
334+
335+
@CreatePermission
336+
@EndpointDoc("Delete smb join auth",
337+
parameters={
338+
'auth_id': (str, 'auth_id')
339+
},
340+
responses={204: None})
341+
def delete(self, auth_id: str) -> None:
342+
"""
343+
Delete smb join auth resource
344+
345+
:param auth_id: Join Auth identifier
346+
:return: None.
347+
"""
348+
resource = {}
349+
resource['resource_type'] = self._resource
350+
resource['auth_id'] = auth_id
351+
resource['intent'] = Intent.REMOVED
352+
return mgr.remote('smb', 'apply_resources', json.dumps(resource)).one().to_simplified()
353+
335354

336355
@APIRouter('/smb/usersgroups', Scope.SMB)
337356
@APIDoc("SMB Users Groups API", "SMB")
@@ -341,19 +360,71 @@ class SMBUsersgroups(RESTController):
341360
@ReadPermission
342361
@EndpointDoc("List smb user resources",
343362
responses={200: LIST_USERSGROUPS_SCHEMA})
344-
def list(self, users_groups: str = '') -> List[Share]:
363+
def list(self) -> List[UsersAndGroups]:
345364
"""
346365
List all smb usersgroups resources
347366
348-
:return: Returns list of usersgroups.
367+
:return: Returns list of usersgroups
349368
:rtype: List[Dict]
350369
"""
351370
res = mgr.remote(
352371
'smb',
353372
'show',
354-
[f'{self._resource}.{users_groups}' if users_groups else self._resource])
373+
[self._resource])
355374
return res['resources'] if 'resources' in res else [res]
356375

376+
@ReadPermission
377+
@EndpointDoc("Get smb usersgroups authorization resource",
378+
responses={200: USERSGROUPS_SCHEMA})
379+
def get(self, users_groups_id: str) -> UsersAndGroups:
380+
"""
381+
Get Users and groups resource
382+
383+
:return: Returns join auth.
384+
:rtype: Dict
385+
"""
386+
res = mgr.remote(
387+
'smb',
388+
'show',
389+
[f'{self._resource}.{users_groups_id}'])
390+
return res['resources'] if 'resources' in res else res
391+
392+
@CreatePermission
393+
@EndpointDoc("Create smb usersgroups",
394+
parameters={
395+
'users_groups_id': (str, 'users_groups_id'),
396+
'username': (str, 'username'),
397+
'password': (str, 'password')
398+
},
399+
responses={201: USERSGROUPS_SCHEMA_RESULTS})
400+
def create(self, usersgroups: UsersAndGroups) -> Simplified:
401+
"""
402+
Create smb usersgroups resource
403+
404+
:return: Returns usersgroups resource.
405+
:rtype: Dict
406+
"""
407+
return mgr.remote('smb', 'apply_resources', json.dumps(usersgroups)).to_simplified()
408+
409+
@CreatePermission
410+
@EndpointDoc("Delete smb join auth",
411+
parameters={
412+
'users_groups_id': (str, 'users_groups_id')
413+
},
414+
responses={204: None})
415+
def delete(self, users_groups_id: str) -> None:
416+
"""
417+
Delete smb usersgroups resource
418+
419+
:param users_group_id: Users identifier
420+
:return: None.
421+
"""
422+
resource = {}
423+
resource['resource_type'] = self._resource
424+
resource['users_groups_id'] = users_groups_id
425+
resource['intent'] = Intent.REMOVED
426+
return mgr.remote('smb', 'apply_resources', json.dumps(resource)).one().to_simplified()
427+
357428

358429
@UIRouter('/smb')
359430
class SMBStatus(RESTController):

src/pybind/mgr/dashboard/frontend/src/app/app-routing.module.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ import { MultiClusterDetailsComponent } from './ceph/cluster/multi-cluster/multi
5454
import { SmbClusterFormComponent } from './ceph/smb/smb-cluster-form/smb-cluster-form.component';
5555
import { SmbTabsComponent } from './ceph/smb/smb-tabs/smb-tabs.component';
5656
import { SmbShareFormComponent } from './ceph/smb/smb-share-form/smb-share-form.component';
57+
import { SmbJoinAuthFormComponent } from './ceph/smb/smb-join-auth-form/smb-join-auth-form.component';
58+
import { SmbUsersgroupsFormComponent } from './ceph/smb/smb-usersgroups-form/smb-usersgroups-form.component';
5759

5860
@Injectable()
5961
export class PerformanceCounterBreadcrumbsResolver extends BreadcrumbsResolver {
@@ -457,6 +459,26 @@ const routes: Routes = [
457459
path: `share/${URLVerbs.CREATE}/:clusterId`,
458460
component: SmbShareFormComponent,
459461
data: { breadcrumbs: ActionLabels.CREATE }
462+
},
463+
{
464+
path: `ad/${URLVerbs.CREATE}`,
465+
component: SmbJoinAuthFormComponent,
466+
data: { breadcrumbs: ActionLabels.CREATE }
467+
},
468+
{
469+
path: `ad/${URLVerbs.EDIT}/:authId`,
470+
component: SmbJoinAuthFormComponent,
471+
data: { breadcrumbs: ActionLabels.EDIT }
472+
},
473+
{
474+
path: `standalone/${URLVerbs.CREATE}`,
475+
component: SmbUsersgroupsFormComponent,
476+
data: { breadcrumbs: ActionLabels.CREATE }
477+
},
478+
{
479+
path: `standalone/${URLVerbs.EDIT}/:usersGroupsId`,
480+
component: SmbUsersgroupsFormComponent,
481+
data: { breadcrumbs: ActionLabels.EDIT }
460482
}
461483
]
462484
}

src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs.module.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import {
5151
} from 'carbon-components-angular';
5252

5353
import AddIcon from '@carbon/icons/es/add/32';
54+
import LaunchIcon from '@carbon/icons/es/launch/32';
5455
import Close from '@carbon/icons/es/close/32';
5556
import Trash from '@carbon/icons/es/trash-can/32';
5657

@@ -109,6 +110,6 @@ import Trash from '@carbon/icons/es/trash-can/32';
109110
})
110111
export class CephfsModule {
111112
constructor(private iconService: IconService) {
112-
this.iconService.registerAll([AddIcon, Close, Trash]);
113+
this.iconService.registerAll([AddIcon, LaunchIcon, Close, Trash]);
113114
}
114115
}

0 commit comments

Comments
 (0)