From 9497cda203a31e292f129625ef934807d6c69402 Mon Sep 17 00:00:00 2001 From: Nizamudeen A Date: Tue, 14 May 2024 14:31:43 +0530 Subject: [PATCH] mgr/dashboard: rgw policy group management api Fixes: https://tracker.ceph.com/issues/66238 Signed-off-by: Nizamudeen A (cherry picked from commit 73a7602806ccd8d6cf4131d1e683233352631713) --- src/pybind/mgr/dashboard/controllers/rgw.py | 45 ++++++++++-- .../mgr/dashboard/services/rgw_client.py | 70 +++++++++++++++++++ 2 files changed, 111 insertions(+), 4 deletions(-) diff --git a/src/pybind/mgr/dashboard/controllers/rgw.py b/src/pybind/mgr/dashboard/controllers/rgw.py index 50b4547a4fe..17b348819a6 100644 --- a/src/pybind/mgr/dashboard/controllers/rgw.py +++ b/src/pybind/mgr/dashboard/controllers/rgw.py @@ -14,11 +14,12 @@ from ..rest_client import RequestException from ..security import Permission, Scope from ..services.auth import AuthManager, JwtManager from ..services.ceph_service import CephService -from ..services.rgw_client import NoRgwDaemonsException, RgwClient, RgwMultisite +from ..services.rgw_client import NoRgwDaemonsException, RgwClient, RgwMultisite, \ + SyncStatus from ..tools import json_str_to_object, str_to_bool from . import APIDoc, APIRouter, BaseController, CreatePermission, \ CRUDCollectionMethod, CRUDEndpoint, Endpoint, EndpointDoc, ReadPermission, \ - RESTController, UIRouter, UpdatePermission, allow_empty_body + RESTController, UIRouter, UpdatePermission, allow_empty_body, DeletePermission from ._crud import CRUDMeta, Form, FormField, FormTaskInfo, Icon, MethodType, \ TableAction, Validator, VerticalContainer from ._version import APIVersion @@ -114,8 +115,9 @@ class RgwMultisiteStatus(RESTController): @APIRouter('rgw/multisite', Scope.RGW) @APIDoc("RGW Multisite Management API", "RgwMultisite") -class RgwMultisiteSyncStatus(RESTController): - @RESTController.Collection(method='GET', path='/sync_status') +class RgwMultisiteController(RESTController): + @Endpoint(path='/sync_status') + @EndpointDoc("Get the sync status") @allow_empty_body # pylint: disable=W0102,W0613 def get_sync_status(self): @@ -123,6 +125,41 @@ class RgwMultisiteSyncStatus(RESTController): result = multisite_instance.get_multisite_sync_status() return result + @Endpoint(path='/sync-policy') + @EndpointDoc("Get the sync policy") + @ReadPermission + def get_sync_policy(self, bucket_name = ''): + multisite_instance = RgwMultisite() + return multisite_instance.get_sync_policy(bucket_name) + + @Endpoint(path='/sync-policy-group') + @EndpointDoc("Get the sync policy group") + @ReadPermission + def get_sync_policy_group(self, group_id: str, bucket_name=''): + multisite_instance = RgwMultisite() + return multisite_instance.get_sync_policy_group(group_id, bucket_name) + + @Endpoint(method='POST', path='/sync-policy-group') + @EndpointDoc("Create the sync policy group") + @CreatePermission + def create_sync_policy_group(self, group_id: str, status: SyncStatus, bucket_name=''): + multisite_instance = RgwMultisite() + return multisite_instance.create_sync_policy_group(group_id, status, bucket_name) + + @Endpoint(method='PUT', path='/sync-policy-group') + @EndpointDoc("Update the sync policy group") + @UpdatePermission + def update_sync_policy_group(self, group_id: str, status: SyncStatus, bucket_name=''): + multisite_instance = RgwMultisite() + return multisite_instance.update_sync_policy_group(group_id, status, bucket_name) + + @Endpoint(method='DELETE', path='/sync-policy-group') + @EndpointDoc("Remove the sync policy group") + @DeletePermission + def remove_sync_policy_group(self, group_id: str, bucket_name=''): + multisite_instance = RgwMultisite() + return multisite_instance.remove_sync_policy_group(group_id, bucket_name) + @APIRouter('/rgw/daemon', Scope.RGW) @APIDoc("RGW Daemon Management API", "RgwDaemon") diff --git a/src/pybind/mgr/dashboard/services/rgw_client.py b/src/pybind/mgr/dashboard/services/rgw_client.py index aed70260362..8f26861766c 100644 --- a/src/pybind/mgr/dashboard/services/rgw_client.py +++ b/src/pybind/mgr/dashboard/services/rgw_client.py @@ -10,6 +10,7 @@ import os import re import xml.etree.ElementTree as ET # noqa: N814 from subprocess import SubprocessError +from enum import Enum from mgr_util import build_url, name_to_config_section @@ -983,6 +984,11 @@ class RgwClient(RestClient): raise DashboardException(msg=msg, component='rgw') return retention_period_days, retention_period_years +class SyncStatus(Enum): + enabled = 'enabled' + allowed = 'allowed' + forbidden = 'forbidden' + class RgwMultisite: def migrate_to_multisite(self, realm_name: str, zonegroup_name: str, zone_name: str, @@ -1744,3 +1750,67 @@ class RgwMultisite: return match.group(1) return '' + + def get_sync_policy(self, bucket_name: str = ''): + rgw_sync_policy_cmd = ['sync', 'policy', 'get'] + if bucket_name: + rgw_sync_policy_cmd += ['--bucket', bucket_name] + try: + exit_code, out, _ = mgr.send_rgwadmin_command(rgw_sync_policy_cmd) + if exit_code > 0: + raise DashboardException('Unable to get sync policy', + http_status_code=500, component='rgw') + return out + except SubprocessError as error: + raise DashboardException(error, http_status_code=500, component='rgw') + + def get_sync_policy_group(self, group_id: str, bucket_name: str = ''): + rgw_sync_policy_cmd = ['sync', 'group', 'get', '--group-id', group_id] + if bucket_name: + rgw_sync_policy_cmd += ['--bucket', bucket_name] + try: + exit_code, out, _ = mgr.send_rgwadmin_command(rgw_sync_policy_cmd) + if exit_code > 0: + raise DashboardException('Unable to get sync policy', + http_status_code=500, component='rgw') + return out + except SubprocessError as error: + raise DashboardException(error, http_status_code=500, component='rgw') + + def create_sync_policy_group(self, group_id: str, status: SyncStatus, bucket_name: str = ''): + rgw_sync_policy_cmd = ['sync', 'group', 'create', '--group-id', group_id, + '--status', SyncStatus[status].value] + if bucket_name: + rgw_sync_policy_cmd += ['--bucket', bucket_name] + try: + exit_code, _, _ = mgr.send_rgwadmin_command(rgw_sync_policy_cmd) + if exit_code > 0: + raise DashboardException('Unable to create sync policy', + http_status_code=500, component='rgw') + except SubprocessError as error: + raise DashboardException(error, http_status_code=500, component='rgw') + + def update_sync_policy_group(self, group_id: str, status: SyncStatus, bucket_name: str = ''): + rgw_sync_policy_cmd = ['sync', 'group', 'modify', '--group-id', group_id, + '--status', SyncStatus[status].value] + if bucket_name: + rgw_sync_policy_cmd += ['--bucket', bucket_name] + try: + exit_code, _, _ = mgr.send_rgwadmin_command(rgw_sync_policy_cmd) + if exit_code > 0: + raise DashboardException('Unable to update sync policy', + http_status_code=500, component='rgw') + except SubprocessError as error: + raise DashboardException(error, http_status_code=500, component='rgw') + + def remove_sync_policy_group(self, group_id: str, bucket_name=''): + rgw_sync_policy_cmd = ['sync', 'group', 'remove', '--group-id', group_id] + if bucket_name: + rgw_sync_policy_cmd += ['--bucket', bucket_name] + try: + exit_code, _, _ = mgr.send_rgwadmin_command(rgw_sync_policy_cmd) + if exit_code > 0: + raise DashboardException('Unable to remove sync policy', + http_status_code=500, component='rgw') + except SubprocessError as error: + raise DashboardException(error, http_status_code=500, component='rgw') -- 2.39.5