From: Imran Imtiaz Date: Mon, 19 Jan 2026 17:02:06 +0000 (+0000) Subject: mgr/dashboard: improve RBD group API endpoint documentation X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=36ef0f86d552247771bfb5b16dd97974bd2aa10e;p=ceph.git mgr/dashboard: improve RBD group API endpoint documentation Signed-off-by: Imran Imtiaz Fixes: https://tracker.ceph.com/issues/74449 Incorporate review comments: - Add namespace description. - Improve group endpoints description. - Remove redundant group name from GET group endpoint. Signed-off-by: Imran Imtiaz --- diff --git a/src/pybind/mgr/dashboard/controllers/rbd.py b/src/pybind/mgr/dashboard/controllers/rbd.py index 341360d1a2a..910c4994dcc 100644 --- a/src/pybind/mgr/dashboard/controllers/rbd.py +++ b/src/pybind/mgr/dashboard/controllers/rbd.py @@ -45,10 +45,9 @@ RBD_GROUP_LIST_SCHEMA = [{ "num_images": (int, '') }] -RBD_GROUP_GET_SCHEMA = [{ - "group": (str, 'group name'), - "images": ([str], '') -}] +RBD_GROUP_GET_SCHEMA = { + "images": ([dict], 'List of images in the group with their pool, namespace, and name') +} RBD_GROUP_SNAPSHOT_LIST_SCHEMA = [{ "id": (str, 'snapshot id'), @@ -485,6 +484,11 @@ class RbdNamespace(RESTController): return result +NAMESPACE_PARAM_DESC = ('Optional RBD namespace within the pool. Provides logical ' + 'isolation of images. When specified, operations are scoped to ' + 'that namespace. If omitted, the default namespace is used.') + + @APIRouter('/block/pool/{pool_name}/group', Scope.RBD_IMAGE) @APIDoc("RBD Group Management API", "RbdGroup") class RbdGroup(RESTController): @@ -493,9 +497,10 @@ class RbdGroup(RESTController): self.rbd_inst = rbd.RBD() @handle_rbd_error() - @EndpointDoc("List groups by pool name", + @EndpointDoc("List all RBD groups in a pool", parameters={ - 'pool_name': (str, 'Name of the pool'), + 'pool_name': (str, 'Name of the pool to list groups from'), + 'namespace': (str, NAMESPACE_PARAM_DESC), }, responses={200: RBD_GROUP_LIST_SCHEMA}) def list(self, pool_name, namespace=None): @@ -512,10 +517,11 @@ class RbdGroup(RESTController): return result @handle_rbd_error() - @EndpointDoc("Get the list of images in a group", + @EndpointDoc("Get details of a specific RBD group including its member images", parameters={ - 'pool_name': (str, 'Name of the pool'), - 'group_name': (str, 'Name of the group'), + 'pool_name': (str, 'Name of the pool containing the group'), + 'group_name': (str, 'Name of the group to retrieve'), + 'namespace': (str, NAMESPACE_PARAM_DESC), }, responses={200: RBD_GROUP_GET_SCHEMA}) @RESTController.Collection('GET', path='/{group_name}') @@ -527,7 +533,6 @@ class RbdGroup(RESTController): groups = self.rbd_inst.group_list(ioctx) if group_name in groups: result.append({ - 'group': group_name, 'images': list(rbd.Group(ioctx, group_name).list_images()) }) else: @@ -538,10 +543,11 @@ class RbdGroup(RESTController): return result @handle_rbd_error() - @EndpointDoc("Create a group", + @EndpointDoc("Create a new RBD group in the specified pool", parameters={ - 'pool_name': (str, 'Name of the pool'), - 'name': (str, 'Name of the group'), + 'pool_name': (str, 'Name of the pool where the group will be created'), + 'name': (str, 'Name for the new group'), + 'namespace': (str, NAMESPACE_PARAM_DESC), }) def create(self, pool_name, name, namespace=None): with mgr.rados.open_ioctx(pool_name) as ioctx: @@ -550,10 +556,11 @@ class RbdGroup(RESTController): return self.rbd_inst.group_create(ioctx, name) @handle_rbd_error() - @EndpointDoc("Delete a group", + @EndpointDoc("Delete an RBD group. All images must be removed from the group first.", parameters={ - 'pool_name': (str, 'Name of the pool'), - 'group_name': (str, 'Name of the group'), + 'pool_name': (str, 'Name of the pool containing the group'), + 'group_name': (str, 'Name of the group to delete'), + 'namespace': (str, NAMESPACE_PARAM_DESC), }, responses={200: None}) def delete(self, pool_name, group_name, namespace=None): @@ -563,11 +570,12 @@ class RbdGroup(RESTController): return self.rbd_inst.group_remove(ioctx, group_name) @handle_rbd_error() - @EndpointDoc("Update a group (rename)", + @EndpointDoc("Rename an existing RBD group", parameters={ - 'pool_name': (str, 'Name of the pool'), - 'group_name': (str, 'Name of the group'), + 'pool_name': (str, 'Name of the pool containing the group'), + 'group_name': (str, 'Current name of the group'), 'new_name': (str, 'New name for the group'), + 'namespace': (str, NAMESPACE_PARAM_DESC), }, responses={200: None}) def set(self, pool_name, group_name, new_name, namespace=None): @@ -580,11 +588,12 @@ class RbdGroup(RESTController): @RESTController.Collection('POST', path='/{group_name}/image') @handle_rbd_error() - @EndpointDoc("Add image to a group", + @EndpointDoc("Add an RBD image to a group. The image must be in the same pool and namespace.", parameters={ - 'pool_name': (str, 'Name of the pool'), - 'group_name': (str, 'Name of the group'), - 'image_name': (str, 'Name of the image'), + 'pool_name': (str, 'Name of the pool containing both the group and image'), + 'group_name': (str, 'Name of the group to add the image to'), + 'image_name': (str, 'Name of the image to add to the group'), + 'namespace': (str, NAMESPACE_PARAM_DESC), }, responses={200: None}) def add_image(self, pool_name, group_name, image_name, namespace=None): @@ -596,11 +605,12 @@ class RbdGroup(RESTController): @RESTController.Collection('DELETE', path='/{group_name}/image') @handle_rbd_error() - @EndpointDoc("Remove image from a group", + @EndpointDoc("Remove an RBD image from a group. The image itself is not deleted.", parameters={ - 'pool_name': (str, 'Name of the pool'), - 'group_name': (str, 'Name of the group'), - 'image_name': (str, 'Name of the image'), + 'pool_name': (str, 'Name of the pool containing the group'), + 'group_name': (str, 'Name of the group to remove the image from'), + 'image_name': (str, 'Name of the image to remove from the group'), + 'namespace': (str, NAMESPACE_PARAM_DESC), }, responses={200: None}) def remove_image(self, pool_name, group_name, image_name, namespace=None): @@ -622,10 +632,11 @@ class RbdGroupSnapshot(RESTController): self.rbd_inst = rbd.RBD() @handle_rbd_error() - @EndpointDoc("List group snapshots", + @EndpointDoc("List all snapshots of an RBD group", parameters={ - 'pool_name': (str, 'Name of the pool'), - 'group_name': (str, 'Name of the group'), + 'pool_name': (str, 'Name of the pool containing the group'), + 'group_name': (str, 'Name of the group to list snapshots for'), + 'namespace': (str, NAMESPACE_PARAM_DESC), }, responses={200: RBD_GROUP_SNAPSHOT_LIST_SCHEMA}) def list(self, pool_name: str, group_name: str, namespace: Optional[str] = None): @@ -644,11 +655,12 @@ class RbdGroupSnapshot(RESTController): return result @handle_rbd_error() - @EndpointDoc("Get group snapshot information", + @EndpointDoc("Get detailed information about a specific group snapshot", parameters={ - 'pool_name': (str, 'Name of the pool'), + 'pool_name': (str, 'Name of the pool containing the group'), 'group_name': (str, 'Name of the group'), - 'snapshot_name': (str, 'Name of the snapshot'), + 'snapshot_name': (str, 'Name of the snapshot to retrieve'), + 'namespace': (str, NAMESPACE_PARAM_DESC), }, responses={200: RBD_GROUP_SNAPSHOT_GET_SCHEMA}) def get(self, pool_name: str, group_name: str, snapshot_name: str, @@ -661,12 +673,13 @@ class RbdGroupSnapshot(RESTController): @RbdTask('group_snap/create', ['{pool_name}', '{group_name}', '{snapshot_name}'], 2.0) - @EndpointDoc("Create a group snapshot", + @EndpointDoc("Create a crash-consistent snapshot of all images in the group", parameters={ - 'pool_name': (str, 'Name of the pool'), - 'group_name': (str, 'Name of the group'), - 'snapshot_name': (str, 'Name of the snapshot'), - 'flags': (int, 'Snapshot creation flags'), + 'pool_name': (str, 'Name of the pool containing the group'), + 'group_name': (str, 'Name of the group to snapshot'), + 'snapshot_name': (str, 'Name for the new snapshot'), + 'namespace': (str, NAMESPACE_PARAM_DESC), + 'flags': (int, 'Snapshot creation flags (optional)'), }, responses={200: None}) def create(self, pool_name: str, group_name: str, snapshot_name: str, @@ -679,11 +692,12 @@ class RbdGroupSnapshot(RESTController): @RbdTask('group_snap/delete', ['{pool_name}', '{group_name}', '{snapshot_name}'], 2.0) - @EndpointDoc("Delete a group snapshot", + @EndpointDoc("Delete a group snapshot. This removes the snapshot for all images in the group.", parameters={ - 'pool_name': (str, 'Name of the pool'), + 'pool_name': (str, 'Name of the pool containing the group'), 'group_name': (str, 'Name of the group'), - 'snapshot_name': (str, 'Name of the snapshot'), + 'snapshot_name': (str, 'Name of the snapshot to delete'), + 'namespace': (str, NAMESPACE_PARAM_DESC), }, responses={200: None}) def delete(self, pool_name: str, group_name: str, snapshot_name: str, @@ -696,12 +710,13 @@ class RbdGroupSnapshot(RESTController): @RbdTask('group_snap/update', ['{pool_name}', '{group_name}', '{snapshot_name}'], 4.0) - @EndpointDoc("Update a group snapshot", + @EndpointDoc("Rename a group snapshot", parameters={ - 'pool_name': (str, 'Name of the pool'), + 'pool_name': (str, 'Name of the pool containing the group'), 'group_name': (str, 'Name of the group'), 'snapshot_name': (str, 'Current name of the snapshot'), 'new_snap_name': (str, 'New name for the snapshot'), + 'namespace': (str, NAMESPACE_PARAM_DESC), }, responses={200: None}) def set(self, pool_name, group_name, snapshot_name, new_snap_name=None, namespace=None): @@ -718,11 +733,12 @@ class RbdGroupSnapshot(RESTController): @RESTController.Resource('POST') @UpdatePermission @allow_empty_body - @EndpointDoc("Rollback group to snapshot", + @EndpointDoc("Rollback all images in the group to their state at the time of the snapshot", parameters={ - 'pool_name': (str, 'Name of the pool'), - 'group_name': (str, 'Name of the group'), - 'snapshot_name': (str, 'Name of the snapshot'), + 'pool_name': (str, 'Name of the pool containing the group'), + 'group_name': (str, 'Name of the group to rollback'), + 'snapshot_name': (str, 'Name of the snapshot to rollback to'), + 'namespace': (str, NAMESPACE_PARAM_DESC), }, responses={200: None}) def rollback(self, pool_name, group_name, snapshot_name, namespace=None): diff --git a/src/pybind/mgr/dashboard/openapi.yaml b/src/pybind/mgr/dashboard/openapi.yaml index e7d9677ee48..37cb26c4dc9 100755 --- a/src/pybind/mgr/dashboard/openapi.yaml +++ b/src/pybind/mgr/dashboard/openapi.yaml @@ -1593,13 +1593,16 @@ paths: /api/block/pool/{pool_name}/group: get: parameters: - - description: Name of the pool + - description: Name of the pool to list groups from in: path name: pool_name required: true schema: type: string - allowEmptyValue: true + description: Optional RBD namespace within the pool. Provides logical isolation + of images. When specified, operations are scoped to that namespace. If omitted, + the default namespace is used. in: query name: namespace schema: @@ -1634,12 +1637,12 @@ paths: trace. security: - jwt: [] - summary: List groups by pool name + summary: List all RBD groups in a pool tags: - RbdGroup post: parameters: - - description: Name of the pool + - description: Name of the pool where the group will be created in: path name: pool_name required: true @@ -1651,9 +1654,12 @@ paths: schema: properties: name: - description: Name of the group + description: Name for the new group type: string namespace: + description: Optional RBD namespace within the pool. Provides logical + isolation of images. When specified, operations are scoped to + that namespace. If omitted, the default namespace is used. type: string required: - name @@ -1680,25 +1686,28 @@ paths: trace. security: - jwt: [] - summary: Create a group + summary: Create a new RBD group in the specified pool tags: - RbdGroup /api/block/pool/{pool_name}/group/{group_name}: delete: parameters: - - description: Name of the pool + - description: Name of the pool containing the group in: path name: pool_name required: true schema: type: string - - description: Name of the group + - description: Name of the group to delete in: path name: group_name required: true schema: type: string - allowEmptyValue: true + description: Optional RBD namespace within the pool. Provides logical isolation + of images. When specified, operations are scoped to that namespace. If omitted, + the default namespace is used. in: query name: namespace schema: @@ -1725,24 +1734,27 @@ paths: trace. security: - jwt: [] - summary: Delete a group + summary: Delete an RBD group. All images must be removed from the group first. tags: - RbdGroup get: parameters: - - description: Name of the pool + - description: Name of the pool containing the group in: path name: pool_name required: true schema: type: string - - description: Name of the group + - description: Name of the group to retrieve in: path name: group_name required: true schema: type: string - allowEmptyValue: true + description: Optional RBD namespace within the pool. Provides logical isolation + of images. When specified, operations are scoped to that namespace. If omitted, + the default namespace is used. in: query name: namespace schema: @@ -1752,21 +1764,16 @@ paths: content: application/vnd.ceph.api.v1.0+json: schema: - items: - properties: - group: - description: group name - type: string - images: - description: '' - items: - type: string - type: array - type: object + properties: + images: + description: List of images in the group with their pool, namespace, + and name + items: + type: object + type: array required: - - group - images - type: array + type: object description: OK '400': description: Operation exception. Please check the response body for details. @@ -1779,18 +1786,18 @@ paths: trace. security: - jwt: [] - summary: Get the list of images in a group + summary: Get details of a specific RBD group including its member images tags: - RbdGroup put: parameters: - - description: Name of the pool + - description: Name of the pool containing the group in: path name: pool_name required: true schema: type: string - - description: Name of the group + - description: Current name of the group in: path name: group_name required: true @@ -1802,6 +1809,9 @@ paths: schema: properties: namespace: + description: Optional RBD namespace within the pool. Provides logical + isolation of images. When specified, operations are scoped to + that namespace. If omitted, the default namespace is used. type: string new_name: description: New name for the group @@ -1833,31 +1843,34 @@ paths: trace. security: - jwt: [] - summary: Update a group (rename) + summary: Rename an existing RBD group tags: - RbdGroup /api/block/pool/{pool_name}/group/{group_name}/image: delete: parameters: - - description: Name of the pool + - description: Name of the pool containing the group in: path name: pool_name required: true schema: type: string - - description: Name of the group + - description: Name of the group to remove the image from in: path name: group_name required: true schema: type: string - - description: Name of the image + - description: Name of the image to remove from the group in: query name: image_name required: true schema: type: string - allowEmptyValue: true + description: Optional RBD namespace within the pool. Provides logical isolation + of images. When specified, operations are scoped to that namespace. If omitted, + the default namespace is used. in: query name: namespace schema: @@ -1884,18 +1897,18 @@ paths: trace. security: - jwt: [] - summary: Remove image from a group + summary: Remove an RBD image from a group. The image itself is not deleted. tags: - RbdGroup post: parameters: - - description: Name of the pool + - description: Name of the pool containing both the group and image in: path name: pool_name required: true schema: type: string - - description: Name of the group + - description: Name of the group to add the image to in: path name: group_name required: true @@ -1907,9 +1920,12 @@ paths: schema: properties: image_name: - description: Name of the image + description: Name of the image to add to the group type: string namespace: + description: Optional RBD namespace within the pool. Provides logical + isolation of images. When specified, operations are scoped to + that namespace. If omitted, the default namespace is used. type: string required: - image_name @@ -1936,25 +1952,29 @@ paths: trace. security: - jwt: [] - summary: Add image to a group + summary: Add an RBD image to a group. The image must be in the same pool and + namespace. tags: - RbdGroup /api/block/pool/{pool_name}/group/{group_name}/snap: get: parameters: - - description: Name of the pool + - description: Name of the pool containing the group in: path name: pool_name required: true schema: type: string - - description: Name of the group + - description: Name of the group to list snapshots for in: path name: group_name required: true schema: type: string - allowEmptyValue: true + description: Optional RBD namespace within the pool. Provides logical isolation + of images. When specified, operations are scoped to that namespace. If omitted, + the default namespace is used. in: query name: namespace schema: @@ -1997,18 +2017,18 @@ paths: trace. security: - jwt: [] - summary: List group snapshots + summary: List all snapshots of an RBD group tags: - RbdGroupSnapshot post: parameters: - - description: Name of the pool + - description: Name of the pool containing the group in: path name: pool_name required: true schema: type: string - - description: Name of the group + - description: Name of the group to snapshot in: path name: group_name required: true @@ -2021,12 +2041,15 @@ paths: properties: flags: default: 0 - description: Snapshot creation flags + description: Snapshot creation flags (optional) type: integer namespace: + description: Optional RBD namespace within the pool. Provides logical + isolation of images. When specified, operations are scoped to + that namespace. If omitted, the default namespace is used. type: string snapshot_name: - description: Name of the snapshot + description: Name for the new snapshot type: string required: - snapshot_name @@ -2053,13 +2076,13 @@ paths: trace. security: - jwt: [] - summary: Create a group snapshot + summary: Create a crash-consistent snapshot of all images in the group tags: - RbdGroupSnapshot /api/block/pool/{pool_name}/group/{group_name}/snap/{snapshot_name}: delete: parameters: - - description: Name of the pool + - description: Name of the pool containing the group in: path name: pool_name required: true @@ -2071,13 +2094,16 @@ paths: required: true schema: type: string - - description: Name of the snapshot + - description: Name of the snapshot to delete in: path name: snapshot_name required: true schema: type: string - allowEmptyValue: true + description: Optional RBD namespace within the pool. Provides logical isolation + of images. When specified, operations are scoped to that namespace. If omitted, + the default namespace is used. in: query name: namespace schema: @@ -2104,12 +2130,13 @@ paths: trace. security: - jwt: [] - summary: Delete a group snapshot + summary: Delete a group snapshot. This removes the snapshot for all images in + the group. tags: - RbdGroupSnapshot get: parameters: - - description: Name of the pool + - description: Name of the pool containing the group in: path name: pool_name required: true @@ -2121,13 +2148,16 @@ paths: required: true schema: type: string - - description: Name of the snapshot + - description: Name of the snapshot to retrieve in: path name: snapshot_name required: true schema: type: string - allowEmptyValue: true + description: Optional RBD namespace within the pool. Provides logical isolation + of images. When specified, operations are scoped to that namespace. If omitted, + the default namespace is used. in: query name: namespace schema: @@ -2178,12 +2208,12 @@ paths: trace. security: - jwt: [] - summary: Get group snapshot information + summary: Get detailed information about a specific group snapshot tags: - RbdGroupSnapshot put: parameters: - - description: Name of the pool + - description: Name of the pool containing the group in: path name: pool_name required: true @@ -2207,6 +2237,9 @@ paths: schema: properties: namespace: + description: Optional RBD namespace within the pool. Provides logical + isolation of images. When specified, operations are scoped to + that namespace. If omitted, the default namespace is used. type: string new_snap_name: description: New name for the snapshot @@ -2236,25 +2269,25 @@ paths: trace. security: - jwt: [] - summary: Update a group snapshot + summary: Rename a group snapshot tags: - RbdGroupSnapshot /api/block/pool/{pool_name}/group/{group_name}/snap/{snapshot_name}/rollback: post: parameters: - - description: Name of the pool + - description: Name of the pool containing the group in: path name: pool_name required: true schema: type: string - - description: Name of the group + - description: Name of the group to rollback in: path name: group_name required: true schema: type: string - - description: Name of the snapshot + - description: Name of the snapshot to rollback to in: path name: snapshot_name required: true @@ -2266,6 +2299,9 @@ paths: schema: properties: namespace: + description: Optional RBD namespace within the pool. Provides logical + isolation of images. When specified, operations are scoped to + that namespace. If omitted, the default namespace is used. type: string type: object responses: @@ -2290,7 +2326,8 @@ paths: trace. security: - jwt: [] - summary: Rollback group to snapshot + summary: Rollback all images in the group to their state at the time of the + snapshot tags: - RbdGroupSnapshot /api/block/pool/{pool_name}/namespace: