]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/rgw: add support to modify zonegroup parameters
authorAdam King <adking@redhat.com>
Mon, 25 Mar 2024 16:13:32 +0000 (12:13 -0400)
committerAdam King <adking@redhat.com>
Tue, 26 Mar 2024 19:31:59 +0000 (15:31 -0400)
This is being done with `radosgw-admin zonegroup set`
rather than `radosgw-admin zonegroup modify` as I don't
think the hostnames parameter (which is the primary focus
for this specific change) can be set using the modify
command. The nice bit about that is it should in theory
make it easy to extend this to allow setting other parameters
to be modified in the zonegroup in the future.

Signed-off-by: Adam King <adking@redhat.com>
(cherry picked from commit 5f7c6d58cc90ff139c1f8f8b950ef37d8597f92f)

src/pybind/mgr/rgw/module.py
src/python-common/ceph/deployment/service_spec.py
src/python-common/ceph/rgw/rgwam_core.py

index f48e2e09fc32350592cc9c7bb4c335ea1ce744ae..1b589541932b066af9a18d52993241195c7ce123 100644 (file)
@@ -28,7 +28,7 @@ if TYPE_CHECKING:
         from typing_extensions import Protocol
 
     class MgrModuleProtocol(Protocol):
-        def tool_exec(self, args: List[str]) -> Tuple[int, str, str]:
+        def tool_exec(self, args: List[str], timeout: int = 10, stdin: Optional[bytes] = None) -> Tuple[int, str, str]:
             ...
 
         def apply_rgw(self, spec: RGWSpec) -> OrchResult[str]:
@@ -66,9 +66,9 @@ class RGWAMOrchMgr(RGWAMEnvMgr):
     def __init__(self, mgr: MgrModuleProtocol):
         self.mgr = mgr
 
-    def tool_exec(self, prog: str, args: List[str]) -> Tuple[List[str], int, str, str]:
+    def tool_exec(self, prog: str, args: List[str], stdin: Optional[bytes] = None) -> Tuple[List[str], int, str, str]:
         cmd = [prog] + args
-        rc, stdout, stderr = self.mgr.tool_exec(args=cmd)
+        rc, stdout, stderr = self.mgr.tool_exec(args=cmd, stdin=stdin)
         return cmd, rc, stdout, stderr
 
     def apply_rgw(self, spec: RGWSpec) -> None:
@@ -286,6 +286,18 @@ class Module(orchestrator.OrchestratorClientMixin, MgrModule):
             self.log.error('cmd run exception: (%d) %s' % (e.retcode, e.message))
             return HandleCommandResult(retval=e.retcode, stdout=e.stdout, stderr=e.stderr)
 
+    @CLICommand('rgw zonegroup modify', perm='rw')
+    def update_zonegroup_info(self, realm_name: str, zonegroup_name: str, zone_name: str, hostnames: List[str]) -> HandleCommandResult:
+        try:
+            retval, out, err = RGWAM(self.env).zonegroup_modify(realm_name,
+                                                                zonegroup_name,
+                                                                zone_name,
+                                                                hostnames)
+            return HandleCommandResult(retval, 'Zonegroup updated successfully', '')
+        except RGWAMException as e:
+            self.log.error('cmd run exception: (%d) %s' % (e.retcode, e.message))
+            return HandleCommandResult(retval=e.retcode, stdout=e.stdout, stderr=e.stderr)
+
     @CLICommand('rgw zone create', perm='rw')
     @check_orchestrator
     def _cmd_rgw_zone_create(self,
index f6d290f071888ce089c55812303d1595802de4e7..3e9e301102462df863047e6396c78603e72eb06c 100644 (file)
@@ -1169,10 +1169,11 @@ class RGWSpec(ServiceSpec):
                  rgw_realm_token: Optional[str] = None,
                  update_endpoints: Optional[bool] = False,
                  zone_endpoints: Optional[str] = None,  # comma separated endpoints list
+                 zonegroup_hostnames: Optional[str] = None,
                  rgw_user_counters_cache: Optional[bool] = False,
                  rgw_user_counters_cache_size: Optional[int] = None,
                  rgw_bucket_counters_cache: Optional[bool] = False,
-                 rgw_bucket_counters_cache_size: Optional[int] = None
+                 rgw_bucket_counters_cache_size: Optional[int] = None,
                  ):
         assert service_type == 'rgw', service_type
 
@@ -1212,6 +1213,7 @@ class RGWSpec(ServiceSpec):
         self.rgw_realm_token = rgw_realm_token
         self.update_endpoints = update_endpoints
         self.zone_endpoints = zone_endpoints
+        self.zonegroup_hostnames = zonegroup_hostnames
 
         #: To track op metrics by user config value rgw_user_counters_cache must be set to true
         self.rgw_user_counters_cache = rgw_user_counters_cache
index 7041ea1544f0069c4cdc4b3e7b08152d0f0ca28a..333f490158525ee5a98d343f43d8814c69de3b0c 100644 (file)
@@ -149,11 +149,12 @@ class RGWCmdBase:
             opt_arg(self.cmd_suffix, '--rgw-zone', zone_env.zone.name)
             opt_arg(self.cmd_suffix, '--zone-id', zone_env.zone.id)
 
-    def run(self, cmd):
+    def run(self, cmd, stdin=None):
         args = cmd + self.cmd_suffix
-        cmd, returncode, stdout, stderr = self.mgr.tool_exec(self.prog, args)
+        cmd, returncode, stdout, stderr = self.mgr.tool_exec(self.prog, args, stdin)
 
         log.debug('cmd=%s' % str(cmd))
+        log.debug(f'stdin={stdin}')
         log.debug('stdout=%s' % stdout)
 
         if returncode != 0:
@@ -174,8 +175,8 @@ class RGWAdminJSONCmd(RGWAdminCmd):
     def __init__(self, zone_env: ZoneEnv):
         super().__init__(zone_env)
 
-    def run(self, cmd):
-        stdout, _ = RGWAdminCmd.run(self, cmd)
+    def run(self, cmd, stdin=None):
+        stdout, _ = RGWAdminCmd.run(self, cmd, stdin)
 
         return json.loads(stdout)
 
@@ -237,9 +238,13 @@ class ZonegroupOp:
     def get(self, zonegroup: EntityKey = None):
         ze = ZoneEnv(self.env)
         params = ['zonegroup', 'get']
-        opt_arg(params, '--rgw-zonegroup', zonegroup)
         return RGWAdminJSONCmd(ze).run(params)
 
+    def set(self, zonegroup: EntityKey, zg_json: str):
+        ze = ZoneEnv(self.env)
+        params = ['zonegroup', 'set']
+        return RGWAdminJSONCmd(ze).run(params, stdin=zg_json.encode('utf-8'))
+
     def create(self, realm: EntityKey, zg: EntityKey = None, endpoints=None, is_master=True):
         ze = ZoneEnv(self.env, realm=realm).init_zg(zg, gen=True)
 
@@ -724,6 +729,43 @@ class RGWAM:
 
         return (0, success_message, '')
 
+    def zonegroup_modify(self, realm_name, zonegroup_name, zone_name, hostnames):
+        if realm_name is None:
+            raise RGWAMException('Realm name is a mandatory parameter')
+        if zone_name is None:
+            raise RGWAMException('Zone name is a mandatory parameter')
+        if zonegroup_name is None:
+            raise RGWAMException('Zonegroup name is a mandatory parameter')
+
+        realm = EntityName(realm_name)
+        zone = EntityName(zone_name)
+        period_info = self.period_op().get(realm)
+        period = RGWPeriod(period_info)
+        logging.info('Period: ' + period.id)
+        zonegroup = period.find_zonegroup_by_name(zonegroup_name)
+        if not zonegroup:
+            raise RGWAMException(f'zonegroup {zonegroup_name} not found')
+        zg = EntityName(zonegroup.name)
+        zg_json = self.zonegroup_op().get(zg)
+
+        if hostnames:
+            zg_json['hostnames'] = hostnames
+
+        try:
+            self.zonegroup_op().set(zg, json.dumps(zg_json))
+        except RGWAMException as e:
+            raise RGWAMException('failed to set zonegroup', e)
+
+        try:
+            period_info = self.period_op().update(realm, zg, zone, True)
+        except RGWAMException as e:
+            raise RGWAMException('failed to update period', e)
+
+        period = RGWPeriod(period_info)
+        logging.debug(period.to_json())
+
+        return (0, f'Modified zonegroup {zonegroup_name} of realm {realm_name}', '')
+
     def get_realms_info(self):
         realms_info = []
         for realm_name in self.realm_op().list():