]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/rgwam: use realm/zonegroup/zone method arguments for period update 59716/head
authorAashish Sharma <aasharma@li-e74156cc-2f67-11b2-a85c-e98659a63c5c.ibm.com>
Wed, 11 Sep 2024 04:36:46 +0000 (10:06 +0530)
committerAashish Sharma <aasharma@li-e74156cc-2f67-11b2-a85c-e98659a63c5c.ibm.com>
Mon, 23 Sep 2024 05:37:50 +0000 (11:07 +0530)
period update method currently uses default zonegroup/zone for period
update commit. This PR is to use realm/zg/zone provided in the arguments
for period update. Also make the realm default that is created using realm pull
if it is the only realm present

Fixes: https://tracker.ceph.com/issues/67897
Signed-off-by: Aashish Sharma <aasharma@redhat.com>
src/pybind/mgr/dashboard/services/rgw_client.py
src/python-common/ceph/rgw/rgwam_core.py

index 013fc0cb0b9f88ff9430a4b93ab66bf761a87c1a..145b77ebe95364e8d6f6bf9a46a2ebecc6775400 100644 (file)
@@ -234,18 +234,27 @@ class RgwClient(RestClient):
 
     @staticmethod
     def _get_daemon_connection_info(daemon_name: str) -> dict:
+        access_key = None
+        secret_key = None
+
         try:
+            # Try to fetch realm-specific credentials first
             realm_name = RgwClient._daemons[daemon_name].realm_name
             access_key = Settings.RGW_API_ACCESS_KEY[realm_name]
             secret_key = Settings.RGW_API_SECRET_KEY[realm_name]
         except TypeError:
-            # Legacy string values.
+            # Handle legacy case where credentials are simple strings, not per-realm
             access_key = Settings.RGW_API_ACCESS_KEY
             secret_key = Settings.RGW_API_SECRET_KEY
         except KeyError as error:
-            raise DashboardException(msg='Credentials not found for RGW Daemon: {}'.format(error),
-                                     http_status_code=404,
-                                     component='rgw')
+            # If the realm-specific credentials are not found, try fetching dashboard user keys
+            rgw_service_manager = RgwServiceManager()
+            # pylint: disable=protected-access
+            access_key, secret_key = rgw_service_manager._get_user_keys('dashboard')
+            if not access_key:
+                raise DashboardException(msg='Credentials not found for RGW Daemon: {}'.format(error),  # noqa E501  # pylint: disable=line-too-long
+                                         http_status_code=404,
+                                         component='rgw')
 
         return {'access_key': access_key, 'secret_key': secret_key}
 
index 312d66362eca28321c93b1ab634284eb611afd02..2f8f1e9208703bf4870f6d4589c15152f9e7d1c8 100644 (file)
@@ -236,7 +236,7 @@ class ZonegroupOp:
             return []
 
     def get(self, zonegroup: EntityKey = None):
-        ze = ZoneEnv(self.env)
+        ze = ZoneEnv(self.env, zg=zonegroup)
         params = ['zonegroup', 'get']
         return RGWAdminJSONCmd(ze).run(params)
 
@@ -323,30 +323,33 @@ class PeriodOp:
         self.env = env
 
     def update(self, realm: EntityKey, zonegroup: EntityKey, zone: EntityKey, commit=True):
-        master_zone_info = self.get_master_zone(realm, zonegroup)
-        master_zone = EntityName(master_zone_info['name']) if master_zone_info else zone
-        master_zonegroup_info = self.get_master_zonegroup(realm)
-        master_zonegroup = EntityName(master_zonegroup_info['name']) \
-            if master_zonegroup_info else zonegroup
-        ze = ZoneEnv(self.env, realm=realm,  zg=master_zonegroup, zone=master_zone)
+        ze = ZoneEnv(self.env, realm=realm,  zg=zonegroup, zone=zone)
         params = ['period', 'update']
         opt_arg_bool(params, '--commit', commit)
         return RGWAdminJSONCmd(ze).run(params)
 
-    def get_master_zone(self, realm, zonegroup=None):
+    def get_master_zone(self, realm, zonegroup):
         try:
-            ze = ZoneEnv(self.env, realm=realm, zg=zonegroup)
-            params = ['zone', 'get']
-            return RGWAdminJSONCmd(ze).run(params)
-        except RGWAMCmdRunException:
+            # Fetch the realm period
+            realm_period = self.get(realm)
+            zonegroups = realm_period['period_map']['zonegroups']
+
+            # Find the master zone in the realm period data
+            for zonegroup_inf in zonegroups:
+                if zonegroup_inf['name'] == zonegroup.name:
+                    for zone in zonegroup_inf.get('zones', []):
+                        if zone['id'] == zonegroup_inf['master_zone']:
+                            return zone
             return None
 
-    def get_master_zone_ep(self, realm, zonegroup=None):
+        except RGWAMCmdRunException as e:
+            log.error(f"Failed to fetch master zone: {e}")
+            return None
+
+    def get_master_zone_ep(self, realm):
         try:
-            ze = ZoneEnv(self.env, realm=realm, zg=zonegroup)
-            params = ['period', 'get']
-            output = RGWAdminJSONCmd(ze).run(params)
-            for zg in output['period_map']['zonegroups']:
+            realm_period = self.get(realm)
+            for zg in realm_period['period_map']['zonegroups']:
                 if not bool(zg['is_master']):
                     continue
                 for zone in zg['zones']:
@@ -358,10 +361,19 @@ class PeriodOp:
 
     def get_master_zonegroup(self, realm):
         try:
-            ze = ZoneEnv(self.env, realm=realm)
-            params = ['zonegroup', 'get']
-            return RGWAdminJSONCmd(ze).run(params)
-        except RGWAMCmdRunException:
+            # Fetch the realm period
+            realm_period = self.get(realm)
+            master_zonegroup_id = realm_period['master_zonegroup']
+            zonegroups = realm_period['period_map']['zonegroups']
+
+            # Find the master zonegroup in the realm period data
+            for zonegroup in zonegroups:
+                if zonegroup['id'] == master_zonegroup_id:
+                    return zonegroup
+            return None
+
+        except RGWAMCmdRunException as e:
+            log.error(f"Failed to fetch master zonegroup: {e}")
             return None
 
     def get(self, realm=None):
@@ -539,7 +551,7 @@ class RGWAM:
         realm = self.create_realm(realm_name)
         zonegroup = self.create_zonegroup(realm, zonegroup_name, zonegroup_is_master=True)
         zone = self.create_zone(realm, zonegroup, zone_name, zone_is_master=True)
-        self.update_period(realm, zonegroup)
+        self.update_period(realm, zonegroup, zone)
 
         # Create system user, normal user and update the master zone
         sys_user = self.create_system_user(realm, zonegroup, zone)
@@ -548,7 +560,7 @@ class RGWAM:
         secret = rgw_acces_key.secret_key if rgw_acces_key else ''
         self.zone_op().modify(zone, zonegroup, None,
                               access_key, secret, endpoints=rgw_spec.zone_endpoints)
-        self.update_period(realm, zonegroup)
+        self.update_period(realm, zonegroup, zone)
 
         if start_radosgw and rgw_spec.zone_endpoints is None:
             # Instruct the orchestrator to start RGW daemons, asynchronically, this will
@@ -770,22 +782,43 @@ class RGWAM:
         realms_info = []
         for realm_name in self.realm_op().list():
             realm = self.get_realm(realm_name)
-            master_zone_inf = self.period_op().get_master_zone(realm)
-            zone_ep = self.period_op().get_master_zone_ep(realm)
-            if master_zone_inf and 'system_key' in master_zone_inf:
-                access_key = master_zone_inf['system_key']['access_key']
-                secret = master_zone_inf['system_key']['secret_key']
-            else:
-                access_key = ''
-                secret = ''
-            realms_info.append({"realm_name": realm_name,
-                                "realm_id": realm.id,
-                                "master_zone_id": master_zone_inf['id'] if master_zone_inf else '',
-                                "endpoint": zone_ep[0] if zone_ep else None,
-                                "access_key": access_key,
-                                "secret": secret})
+            realm_period = self.period_op().get(realm)
+            master_zone_id = realm_period['master_zone']
+            master_zone_name = self.get_master_zone_name(realm_period, master_zone_id)
+            local_zone_list = self.zone_op().list()
+
+            # Only consider the realm if master_zone_name is in the local zone list
+            if master_zone_name in local_zone_list:
+                master_zone_inf = self.zone_op().get(EntityID(master_zone_id))
+                zone_ep = self.period_op().get_master_zone_ep(realm)
+
+                if master_zone_inf and 'system_key' in master_zone_inf:
+                    access_key = master_zone_inf['system_key']['access_key']
+                    secret = master_zone_inf['system_key']['secret_key']
+                else:
+                    access_key = ''
+                    secret = ''
+
+                realms_info.append({
+                    "realm_name": realm_name,
+                    "realm_id": realm.id,
+                    "master_zone_id": master_zone_inf['id'] if master_zone_inf else '',
+                    "endpoint": zone_ep[0] if zone_ep else None,
+                    "access_key": access_key,
+                    "secret": secret
+                })
+
         return realms_info
 
+    def get_master_zone_name(self, realm_data, master_zone_id):
+        # Find the zonegroups in the period_map
+        zonegroups = realm_data.get('period_map', {}).get('zonegroups', [])
+        for zonegroup in zonegroups:
+            for zone in zonegroup.get('zones', []):
+                if zone.get('id') == master_zone_id:
+                    return zone.get('name')
+        return None
+
     def zone_create(self, rgw_spec, start_radosgw, secondary_zone_period_retry_limit=5):
 
         if not rgw_spec.rgw_realm_token:
@@ -811,7 +844,7 @@ class RGWAM:
         realm_name = realm_info['name']
         realm_id = realm_info['id']
 
-        realm = EntityID(realm_id)
+        realm = EntityKey(realm_name, realm_id)
         period_info = self.period_op().get(realm)
         period = RGWPeriod(period_info)
         logging.info('Period: ' + period.id)