From 6a40c6d3e2b07ae1f84b2d892e65f01ed07d0f41 Mon Sep 17 00:00:00 2001 From: Nizamudeen A Date: Mon, 6 Jun 2022 11:21:29 +0530 Subject: [PATCH] mgr/dashboard: configure rbd mirroring One-click button in the case of an orch cluster for configuring the rbd-mirroring when its not properly setup. This button will create an rbd-mirror service and also an rbd labelled pool(replicated: size-3) (if they are not existing) Fixes: https://tracker.ceph.com/issues/55646 Signed-off-by: Nizamudeen A Conflicts: src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.html src/pybind/mgr/dashboard/frontend/src/app/shared/services/module-status-guard.service.ts src/pybind/mgr/dashboard/tests/test_rbd_mirroring.py error component and module-status-guard.service.ts had one minor conflict which was resolved by getting incoming changes (add missing logic). test_rbd_mirroring had an import conflict which was resolved by accepting incoming changes which had the same imports with new ones. --- src/pybind/mgr/dashboard/controllers/pool.py | 6 +++ .../dashboard/controllers/rbd_mirroring.py | 46 ++++++++++++++++++- .../src/app/ceph/block/block.module.ts | 15 +++++- .../src/app/core/error/error.component.html | 12 +++++ .../src/app/core/error/error.component.ts | 41 ++++++++++++++++- .../services/module-status-guard.service.ts | 5 ++ .../mgr/dashboard/tests/test_rbd_mirroring.py | 26 ++++++++++- 7 files changed, 145 insertions(+), 6 deletions(-) diff --git a/src/pybind/mgr/dashboard/controllers/pool.py b/src/pybind/mgr/dashboard/controllers/pool.py index c653575dea559..8e8a87b98c914 100644 --- a/src/pybind/mgr/dashboard/controllers/pool.py +++ b/src/pybind/mgr/dashboard/controllers/pool.py @@ -344,3 +344,9 @@ class PoolUi(Pool): "used_profiles": used_profiles, 'nodes': mgr.get('osd_map_tree')['nodes'] } + + +class RBDPool(Pool): + def create(self, pool='rbd-mirror'): # pylint: disable=arguments-differ + super().create(pool, pg_num=1, pool_type='replicated', + rule_name='replicated_rule', application_metadata=['rbd']) diff --git a/src/pybind/mgr/dashboard/controllers/rbd_mirroring.py b/src/pybind/mgr/dashboard/controllers/rbd_mirroring.py index 53210a3180372..b2c0527cc72ff 100644 --- a/src/pybind/mgr/dashboard/controllers/rbd_mirroring.py +++ b/src/pybind/mgr/dashboard/controllers/rbd_mirroring.py @@ -11,13 +11,17 @@ import cherrypy import rbd from .. import mgr +from ..controllers.pool import RBDPool +from ..controllers.service import Service from ..security import Scope from ..services.ceph_service import CephService from ..services.exception import handle_rados_error, handle_rbd_error, serialize_dashboard_exception +from ..services.orchestrator import OrchClient from ..services.rbd import rbd_call from ..tools import ViewCache -from . import APIDoc, APIRouter, BaseController, Endpoint, EndpointDoc, \ - ReadPermission, RESTController, Task, UpdatePermission, allow_empty_body +from . import APIDoc, APIRouter, BaseController, CreatePermission, Endpoint, \ + EndpointDoc, ReadPermission, RESTController, Task, UIRouter, \ + UpdatePermission, allow_empty_body try: from typing import no_type_check @@ -595,3 +599,41 @@ class RbdMirroringPoolPeer(RESTController): rbd.RBD().mirror_peer_set_attributes(ioctx, peer_uuid, attributes) _reset_view_cache() + + +@UIRouter('/block/mirroring', Scope.RBD_MIRRORING) +class RbdMirroringStatus(BaseController): + @EndpointDoc('Display RBD Mirroring Status') + @Endpoint() + @ReadPermission + def status(self): + status = {'available': True, 'message': None} + orch_status = OrchClient.instance().status() + + # if the orch is not available we can't create the service + # using dashboard. + if not orch_status['available']: + return status + if not CephService.get_service_list('rbd-mirror') or not CephService.get_pool_list('rbd'): + status['available'] = False + status['message'] = 'RBD mirroring is not configured' # type: ignore + return status + + @Endpoint('POST') + @EndpointDoc('Configure RBD Mirroring') + @CreatePermission + def configure(self): + rbd_pool = RBDPool() + service = Service() + + service_spec = { + 'service_type': 'rbd-mirror', + 'placement': {}, + 'unmanaged': False + } + + if not CephService.get_service_list('rbd-mirror'): + service.create(service_spec, 'rbd-mirror') + + if not CephService.get_pool_list('rbd'): + rbd_pool.create() diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts index ae569aab449da..40fffc2bce749 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts @@ -139,8 +139,19 @@ const routes: Routes = [ { path: 'mirroring', component: RbdMirroringComponent, - canActivate: [FeatureTogglesGuardService], - data: { breadcrumbs: 'Mirroring' }, + canActivate: [FeatureTogglesGuardService, ModuleStatusGuardService], + data: { + moduleStatusGuardConfig: { + uiApiPath: 'block/mirroring', + redirectTo: 'error', + header: $localize`RBD mirroring is not configured`, + button_name: $localize`Configure RBD Mirroring`, + button_title: $localize`This will create rbd-mirror service and a replicated RBD pool`, + component: 'RBD Mirroring', + uiConfig: true + }, + breadcrumbs: 'Mirroring' + }, children: [ { path: `${URLVerbs.EDIT}/:pool_name`, diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.html index 93438532e7403..68436b26aea3f 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/error/error.component.html @@ -27,6 +27,18 @@ the {{ section_info }} management functionality.

+
+ + + +
+