self.mgr.set_health_warning('CEPHADM_FAILED_SET_OPTION', f'Failed to set {len(options_failed_to_set)} option(s)', len(
options_failed_to_set), options_failed_to_set)
+ def _update_rgw_endpoints(self, rgw_spec: RGWSpec) -> None:
+
+ if not rgw_spec.update_endpoints or rgw_spec.rgw_realm_token is None:
+ return
+
+ ep = []
+ protocol = 'https' if rgw_spec.ssl else 'http'
+ for s in self.mgr.cache.get_daemons_by_service(rgw_spec.service_name()):
+ if s.ports:
+ for p in s.ports:
+ ep.append(f'{protocol}://{s.hostname}:{p}')
+ zone_update_cmd = {
+ 'prefix': 'rgw zone update',
+ 'realm_name': rgw_spec.rgw_realm,
+ 'zonegroup_name': rgw_spec.rgw_zonegroup,
+ 'zone_name': rgw_spec.rgw_zone,
+ 'realm_token': rgw_spec.rgw_realm_token,
+ 'endpoints': ep,
+ }
+ self.log.debug(f'rgw cmd: {zone_update_cmd}')
+ rc, out, err = self.mgr.mon_command(zone_update_cmd)
+ rgw_spec.update_endpoints = (rc != 0) # keep trying on failure
+ if rc != 0:
+ self.log.error(f'Error when trying to update rgw zone {err}')
+ self.mgr.set_health_warning('CEPHADM_RGW', 'Cannot update rgw endpoints', 1,
+ [f'Cannot update rgw endpoints for daemon {rgw_spec.service_name()}'])
+ else:
+ self.mgr.remove_health_warning('CEPHADM_RGW')
+
def _apply_service(self, spec: ServiceSpec) -> bool:
"""
Schedule a service. Deploy new daemons or remove old ones, depending
self.mgr._schedule_daemon_action(active_mgr.name(), 'restart')
if service_type == 'rgw':
- rgw_spec = cast(RGWSpec, spec)
- if rgw_spec.update_endpoints and rgw_spec.rgw_realm_token is not None:
- ep = []
- for s in self.mgr.cache.get_daemons_by_service(rgw_spec.service_name()):
- if s.ports:
- for p in s.ports:
- ep.append(f'http://{s.hostname}:{p}')
- zone_update_cmd = {
- 'prefix': 'rgw zone update',
- 'realm_name': rgw_spec.rgw_realm,
- 'zonegroup_name': rgw_spec.rgw_zonegroup,
- 'zone_name': rgw_spec.rgw_zone,
- 'realm_token': rgw_spec.rgw_realm_token,
- 'endpoints': ep,
- }
- self.log.debug(f'rgw cmd: {zone_update_cmd}')
- rc, out, err = self.mgr.mon_command(zone_update_cmd)
- rgw_spec.update_endpoints = (rc != 0) # keep trying on failure
- if rc != 0:
- self.log.error(f'Error when trying to update rgw zone {err}.. keep trying')
+ self._update_rgw_endpoints(cast(RGWSpec, spec))
# remove any?
def _ok_to_stop(remove_daemons: List[orchestrator.DaemonDescription]) -> bool:
start_radosgw: Optional[bool] = True,
inbuf: Optional[str] = None):
"""Bootstrap new rgw realm, zonegroup, and zone"""
- try:
- if inbuf:
- rgw_specs = self._parse_rgw_specs(inbuf)
- elif (realm_name and zonegroup_name and zone_name):
- placement_spec = PlacementSpec.from_string(placement) if placement else None
- rgw_specs = [RGWSpec(rgw_realm=realm_name,
- rgw_zonegroup=zonegroup_name,
- rgw_zone=zone_name,
- rgw_frontend_port=port,
- placement=placement_spec)]
- else:
- return HandleCommandResult(retval=-errno.EINVAL, stdout='', stderr='Invalid arguments: -h or --help for usage')
+ if inbuf:
+ rgw_specs = self._parse_rgw_specs(inbuf)
+ elif (realm_name and zonegroup_name and zone_name):
+ placement_spec = PlacementSpec.from_string(placement) if placement else None
+ rgw_specs = [RGWSpec(rgw_realm=realm_name,
+ rgw_zonegroup=zonegroup_name,
+ rgw_zone=zone_name,
+ rgw_frontend_port=port,
+ placement=placement_spec)]
+ else:
+ err_msg = 'Invalid arguments: either pass a spec with -i or provide the realm, zonegroup and zone.'
+ return HandleCommandResult(retval=-errno.EINVAL, stdout='', stderr=err_msg)
+
+ try:
for spec in rgw_specs:
RGWAM(self.env).realm_bootstrap(spec, start_radosgw)
-
except RGWAMException as e:
self.log.error('cmd run exception: (%d) %s' % (e.retcode, e.message))
return (e.retcode, e.message, e.stderr)
return HandleCommandResult(retval=0, stdout="Realm(s) created correctly. Please, use 'ceph rgw realm tokens' to get the token.", stderr='')
- def _parse_rgw_specs(self, inbuf: Optional[str] = None):
+ def _parse_rgw_specs(self, inbuf: Optional[str] = None) -> List[RGWSpec]:
"""Parse RGW specs from a YAML file."""
# YAML '---' document separator with no content generates
# None entries in the output. Let's skip them silently.
specs = [o for o in yaml_objs if o is not None]
rgw_specs = []
for spec in specs:
- # TODO(rkachach): should we use a new spec instead of RGWSpec here!
rgw_spec = RGWSpec.from_json(spec)
rgw_spec.validate()
rgw_specs.append(rgw_spec)
@CLICommand('rgw realm tokens', perm='r')
def list_realm_tokens(self):
- realms_info = []
- for realm_info in RGWAM(self.env).get_realms_info():
- if not realm_info['master_zone_id']:
- realms_info.append({'realm': realm_info['realm_name'], 'token': 'realm has no master zone'})
- elif not realm_info['endpoint']:
- realms_info.append({'realm': realm_info['realm_name'], 'token': 'master zone has no endpoint'})
- elif not (realm_info['access_key'] and realm_info['secret']):
- realms_info.append({'realm': realm_info['realm_name'], 'token': 'master zone has no access/secret keys'})
- else:
- keys = ['realm_name', 'realm_id', 'is_primary', 'endpoint', 'access_key', 'secret']
- realm_token = RealmToken(**{k: realm_info[k] for k in keys})
- realm_token_b = realm_token.to_json().encode('utf-8')
- realm_token_s = base64.b64encode(realm_token_b).decode('utf-8')
- realms_info.append({'realm': realm_info['realm_name'], 'token': realm_token_s})
-
- return HandleCommandResult(retval=0, stdout=json.dumps(realms_info), stderr='')
+ try:
+ realms_info = []
+ for realm_info in RGWAM(self.env).get_realms_info():
+ if not realm_info['master_zone_id']:
+ realms_info.append({'realm': realm_info['realm_name'], 'token': 'realm has no master zone'})
+ elif not realm_info['endpoint']:
+ realms_info.append({'realm': realm_info['realm_name'], 'token': 'master zone has no endpoint'})
+ elif not (realm_info['access_key'] and realm_info['secret']):
+ realms_info.append({'realm': realm_info['realm_name'], 'token': 'master zone has no access/secret keys'})
+ else:
+ keys = ['realm_name', 'realm_id', 'is_primary', 'endpoint', 'access_key', 'secret']
+ realm_token = RealmToken(**{k: realm_info[k] for k in keys})
+ realm_token_b = realm_token.to_json().encode('utf-8')
+ realm_token_s = base64.b64encode(realm_token_b).decode('utf-8')
+ realms_info.append({'realm': realm_info['realm_name'], 'token': realm_token_s})
+ except RGWAMException as e:
+ self.log.error(f'cmd run exception: ({e.retcode}) {e.message}')
+ return (e.retcode, e.message, e.stderr)
+
+ return HandleCommandResult(retval=0, stdout=json.dumps(realms_info, indent=4), stderr='')
@CLICommand('rgw zone update', perm='rw')
def update_zone_info(self, realm_name: str, zonegroup_name: str, zone_name: str, realm_token: str, endpoints: List[str]):
start_radosgw: Optional[bool] = True,
inbuf: Optional[str] = None):
"""Bootstrap new rgw zone that syncs with existing zone"""
- try:
- if inbuf:
- rgw_specs = self._parse_rgw_specs(inbuf)
- elif (zone_name and realm_token):
- placement_spec = PlacementSpec.from_string(placement) if placement else None
- rgw_specs = [RGWSpec(rgw_realm_token=realm_token,
- rgw_zone=zone_name,
- rgw_frontend_port=port,
- placement=placement_spec)]
- else:
- return HandleCommandResult(retval=-errno.EINVAL, stdout='', stderr='Invalid arguments: -h or --help for usage')
+ if inbuf:
+ rgw_specs = self._parse_rgw_specs(inbuf)
+ elif (zone_name and realm_token):
+ placement_spec = PlacementSpec.from_string(placement) if placement else None
+ rgw_specs = [RGWSpec(rgw_realm_token=realm_token,
+ rgw_zone=zone_name,
+ rgw_frontend_port=port,
+ placement=placement_spec)]
+ else:
+ err_msg = 'Invalid arguments: either pass a spec with -i or provide the zone_name and realm_token.'
+ return HandleCommandResult(retval=-errno.EINVAL, stdout='', stderr=err_msg)
+
+ try:
for rgw_spec in rgw_specs:
retval, out, err = RGWAM(self.env).zone_create(rgw_spec, start_radosgw)
if retval != 0:
break
-
except RGWAMException as e:
self.log.error('cmd run exception: (%d) %s' % (e.retcode, e.message))
return (e.retcode, e.message, e.stderr)
params = ['realm', 'list']
output = RGWAdminJSONCmd(ze).run(params)
return output.get('realms') or []
- except RGWAMException:
+ except RGWAMException as e:
+ logging.info(f'Exception while listing realms {e.message}')
# in case the realm list is empty an exception is raised
return []
params = ['zonegroup', 'list']
output = RGWAdminJSONCmd(ze).run(params)
return output.get('zonegroups') or []
- except RGWAMException:
+ except RGWAMException as e:
+ logging.info(f'Exception while listing zonegroups {e.message}')
return []
def get(self, zonegroup: EntityKey = None):
params = ['zone', 'list']
output = RGWAdminJSONCmd(ze).run(params)
return output.get('zones') or []
- except RGWAMException:
+ except RGWAMException as e:
+ logging.info(f'Exception while listing zones {e.message}')
return []
def get(self, zone: EntityKey):
uid_prefix='user-sys',
is_system=True)
sys_user = RGWUser(sys_user_info)
- logging.info('Created system user: %s' % sys_user.uid)
+ logging.info(f'Created system user: {sys_user.uid} on {realm.name}/{zonegroup.name}/{zone.name}')
access_key = sys_user.keys[0].access_key if sys_user and sys_user.keys else ''
secret_key = sys_user.keys[0].secret_key if sys_user and sys_user.keys else ''
sys_user.add_key(access_key, secret_key)
try:
user_info = self.user_op().create(zone, zg, uid=uid, is_system=False)
user = RGWUser(user_info)
- logging.info('Created regular user: %s' % user.uid)
+ logging.info('Created regular user {user.uid} on {realm.name}/{zonegroup.name}/{zone.name}')
return user
except RGWAMException as e:
raise RGWAMException('failed to create user', e)