zonegroup_endpoints=None, zone_name=None, tier_type=None,
zone_endpoints=None, username=None, cluster_fsid=None,
replication_zone_name=None, cluster_details=None,
- selectedRealmName=None):
+ selectedRealmName=None, secondary_tier_type=None):
multisite_instance = RgwMultisiteAutomation()
result = multisite_instance.setup_multisite_replication(realm_name, zonegroup_name,
zonegroup_endpoints, zone_name,
username, cluster_fsid,
replication_zone_name,
cluster_details,
- selectedRealmName)
+ selectedRealmName,
+ secondary_tier_type)
return result
@RESTController.Collection(method='PUT', path='/setup-rgw-credentials')
@UpdatePermission
@allow_empty_body
# pylint: disable=W0613
- def import_realm_token(self, realm_token, zone_name, port, placement_spec=None):
+ def import_realm_token(self, realm_token, zone_name, port, placement_spec=None, tier_type=None):
try:
- result = CephService.import_realm_token(realm_token, zone_name, port, placement_spec)
+ result = CephService.import_realm_token(realm_token, zone_name, port, placement_spec,
+ tier_type)
return result
except NoRgwDaemonsException as e:
raise DashboardException(e, http_status_code=404, component='rgw')
i18n>The chosen zone name is already in use.</span>
</div>
</div>
-
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input"
+ id="archive_zone"
+ type="checkbox"
+ formControlName="archive_zone">
+ <label class="custom-control-label cds-ml-2"
+ for="archive_zone"
+ i18n>Archive</label>
+ <cd-helper i18n>
+ <span
+ >Enable archival storage to keep all object versions and protect data from deletion or corruption.</span
+ >
+ </cd-helper>
+ </div>
+ </div>
+ </div>
<legend i18n>Service Details</legend>
<div class="form-group row">
<div class="cd-col-form-offset">
id="unmanaged"
type="checkbox"
formControlName="unmanaged">
- <label class="custom-control-label"
+ <label class="custom-control-label cds-ml-2"
for="unmanaged"
i18n>Unmanaged</label>
<cd-helper i18n>If set to true, the orchestrator will not start nor stop any daemon associated with this service.
]),
hosts: new FormControl([]),
count: new FormControl(null, [CdValidators.number(false)]),
- unmanaged: new FormControl(false)
+ unmanaged: new FormControl(false),
+ archive_zone: new FormControl(false)
});
}
const placementSpec: object = {
placement: {}
};
+ const tier_type: string = values['archive_zone'] ? 'archive' : '';
if (!values['unmanaged']) {
switch (values['placement']) {
case 'hosts':
values['realmToken'],
values['zoneName'],
values['rgw_frontend_port'],
- placementSpec
+ placementSpec,
+ tier_type
)
.subscribe(
() => {
i18n>This field is required.</span>
</div>
</div>
+ <div class="form-group row">
+ <div class="cd-col-form-offset">
+ <input type="checkbox"
+ formControlName="secondary_archive_zone"
+ id="secondary_archive_zone">
+ <label for="secondary_archive_zone"
+ class="custom-control-label cds-ml-3"
+ i18n>Archive</label>
+ <cd-help-text>
+ <span i18n>Enable archival storage to keep all object versions and protect data from deletion or corruption.</span>
+ </cd-help-text>
+ </div>
+ </div>
</ng-template>
<div *ngSwitchCase="3"
class="ms-5">
validators: [Validators.required]
}),
configType: new UntypedFormControl(ConfigType.NewRealm, {}),
- selectedRealm: new UntypedFormControl(null, {})
+ selectedRealm: new UntypedFormControl(null, {}),
+ secondary_archive_zone: new UntypedFormControl(false, {})
});
if (!this.isMultiClusterConfigured) {
} else {
const cluster = values['cluster'];
const replicationZoneName = values['replicationZoneName'];
+ const secondaryTierType = values['secondary_archive_zone'] ? 'archive' : '';
let selectedRealmName = '';
if (this.multisiteSetupForm.get('configType').value === ConfigType.ExistingRealm) {
username,
cluster,
replicationZoneName,
+ secondaryTierType,
this.clusterDetailsArray,
selectedRealmName
)
username: string,
cluster?: string,
replicationZoneName?: string,
+ secondaryTierType?: string,
clusterDetailsArray?: any,
selectedRealmName?: string
) {
params = params.set('selectedRealmName', selectedRealmName);
}
+ if (secondaryTierType) {
+ params = params.set('secondary_tier_type', secondaryTierType);
+ }
+
return this.http.post(`${this.uiUrl}/multisite-replications`, null, { params: params });
}
};
}
- importRealmToken(realm_token: string, zone_name: string, port: number, placementSpec: object) {
+ importRealmToken(
+ realm_token: string,
+ zone_name: string,
+ port: number,
+ placementSpec: object,
+ tier_type: string
+ ) {
let requestBody = {
realm_token: realm_token,
zone_name: zone_name,
port: port,
- placement_spec: placementSpec
+ placement_spec: placementSpec,
+ tier_type: tier_type
};
return this.http.post(`${this.url}/import_realm_token`, requestBody);
}
type: string
realm_token:
type: string
+ tier_type:
+ type: string
zone_name:
type: string
required:
return tokens_info
@classmethod
- def import_realm_token(cls, realm_token, zone_name, port, placement_spec):
+ def import_realm_token(cls, realm_token, zone_name, port, placement_spec, tier_type=None):
tokens_info = mgr.remote('rgw', 'import_realm_token', zone_name=zone_name,
realm_token=realm_token, port=port, placement=placement_spec,
- start_radosgw=True)
+ tier_type=tier_type, start_radosgw=True)
return tokens_info
@classmethod
username: str, cluster_fsid: Optional[str] = None,
replication_zone_name: Optional[str] = None,
cluster_details: Optional[str] = None,
- selectedRealmName: Optional[str] = None):
+ selectedRealmName: Optional[str] = None,
+ secondary_tier_type: Optional[str] = None):
logger.info("Starting multisite replication setup")
return self.export_and_import_realm(
realm_name, zonegroup_name, cluster_fsid, replication_zone_name,
- cluster_details_dict, selectedRealmName, username
+ cluster_details_dict, selectedRealmName, username, secondary_tier_type
)
def get_updated_endpoints(self, endpoints: str, orch: OrchClient) -> list[str]:
def export_and_import_realm(self, realm: str, zg: str,
fsid: Optional[str], rep_zone: Optional[str],
details_dict: dict, selectedRealm: Optional[str],
- username: str):
+ username: str, secondary_tier_type: Optional[str] = None):
try:
realm_token_info = CephService.get_realm_tokens()
if fsid and realm_token_info and rep_zone and details_dict:
configuration, and establishing the target zone"
)
self.import_realm_token_to_cluster(fsid, realm, zg, realm_token_info, username,
- rep_zone, details_dict, selectedRealm)
+ rep_zone, details_dict, selectedRealm,
+ secondary_tier_type)
else:
self.update_progress("Realm Export Token fetched successfully", 'complete')
logger.info("Multisite replication setup completed")
def import_realm_token_to_cluster(self, cluster_fsid, realm_name, zonegroup_name,
realm_token_info, username, replication_zone_name,
- cluster_details, selectedRealmName):
+ cluster_details, selectedRealmName,
+ secondary_tier_type=None):
try:
if selectedRealmName:
rgw_service_manager = RgwServiceManager()
token_import_response = self._import_realm_token(
cluster_url, cluster_token, realm_export_token,
- replication_zone_name)
+ replication_zone_name, secondary_tier_type)
self.progress_done += 1
self.update_progress(
token=cluster_token)
logger.info("setting config response: %s", config_info)
- def _import_realm_token(self, cluster_url, cluster_token, realm_token, zone_name):
+ def _import_realm_token(self, cluster_url, cluster_token, realm_token, zone_name,
+ secondary_tier_type=None):
multi_cluster_instance = MultiCluster()
# pylint: disable=protected-access
available_port = multi_cluster_instance._proxy(
'port': available_port,
'placement_spec': {"placement": {}}
}
+ if secondary_tier_type:
+ payload['tier_type'] = secondary_tier_type
# pylint: disable=protected-access
token_import_response = multi_cluster_instance._proxy(
method='POST', base_url=cluster_url, path='api/rgw/realm/import_realm_token',
"""Bootstrap new rgw zone that syncs with zone on another cluster in the same realm"""
try:
- created_zones = self.rgw_zone_create(zone_name, realm_token, port, placement,
- start_radosgw, zone_endpoints, self.secondary_zone_period_retry_limit, inbuf)
+ created_zones = self.rgw_zone_create(zone_name=zone_name,
+ realm_token=realm_token,
+ port=port,
+ placement=placement,
+ start_radosgw=start_radosgw,
+ zone_endpoints=zone_endpoints,
+ secondary_zone_period_retry_limit=self.secondary_zone_period_retry_limit,
+ inbuf=inbuf)
return HandleCommandResult(retval=0, stdout=f"Zones {', '.join(created_zones)} created successfully")
except RGWAMException as e:
return HandleCommandResult(retval=e.retcode, stderr=f'Failed to create zone: {str(e)}')
realm_token: Optional[str] = None,
port: Optional[int] = None,
placement: Optional[Union[str, Dict[str, Any]]] = None,
+ tier_type: Optional[str] = None,
start_radosgw: Optional[bool] = True,
zone_endpoints: Optional[str] = None,
secondary_zone_period_retry_limit: Optional[int] = None,
try:
created_zones = []
for rgw_spec in rgw_specs:
- RGWAM(self.env).zone_create(rgw_spec, start_radosgw, secondary_zone_period_retry_limit)
+ RGWAM(self.env).zone_create(rgw_spec, start_radosgw,
+ secondary_zone_period_retry_limit,
+ tier_type)
if rgw_spec.rgw_zone is not None:
created_zones.append(rgw_spec.rgw_zone)
return created_zones
realm_token: Optional[str] = None,
port: Optional[int] = None,
placement: Optional[dict] = None,
+ tier_type: Optional[str] = None,
start_radosgw: Optional[bool] = True,
zone_endpoints: Optional[str] = None) -> None:
placement_spec = placement.get('placement') if placement else None
- self.rgw_zone_create(zone_name, realm_token, port, placement_spec, start_radosgw,
+ self.rgw_zone_create(zone_name, realm_token, port, placement_spec, tier_type, start_radosgw,
zone_endpoints, secondary_zone_period_retry_limit=5)
def create(self, realm: EntityKey, zonegroup: EntityKey, zone: EntityKey = None,
endpoints=None, is_master=True,
- access_key=None, secret=None):
+ access_key=None, secret=None,
+ tier_type=None, master_zone_name=None):
ze = ZoneEnv(self.env, realm=realm, zg=zonegroup).init_zone(zone, gen=True)
opt_arg(params, '--access-key', access_key)
opt_arg(params, '--secret', secret)
opt_arg(params, '--endpoints', endpoints)
+ opt_arg(params, '--tier-type', tier_type)
+
+ if tier_type == 'archive':
+ opt_arg(params, '--sync-from-all', 'false')
+ opt_arg(params, '--sync-from', master_zone_name)
return RGWAdminJSONCmd(ze).run(params)
raise RGWAMException('failed to create zonegroup', e)
def create_zone(self, realm, zg, zone_name, zone_is_master, access_key=None,
- secret=None, endpoints=None):
+ secret=None, endpoints=None, tier_type=None,
+ master_zone_name=None):
try:
zone_info = self.zone_op().create(realm, zg,
EntityName(zone_name),
endpoints,
is_master=zone_is_master,
access_key=access_key,
- secret=secret)
+ secret=secret,
+ tier_type=tier_type,
+ master_zone_name=master_zone_name)
zone = EntityKey(zone_info['name'], zone_info['id'])
logging.info(f'Created zone name={zone.name} id={zone.id}')
return zone.get('name')
return None
- def zone_create(self, rgw_spec, start_radosgw, secondary_zone_period_retry_limit=5):
+ def zone_create(self, rgw_spec, start_radosgw, secondary_zone_period_retry_limit=5,
+ tier_type=None):
if not rgw_spec.rgw_realm_token:
raise RGWAMException('missing realm token')
logging.info('Period: ' + period.id)
zonegroup = period.get_master_zonegroup()
+ master_zone = self.period_op().get_master_zone(realm, zonegroup)
+ master_zone_name = master_zone['name'] if master_zone else None
if not zonegroup:
raise RGWAMException(f'Cannot find master zonegroup of realm {realm_name}')
zone = self.create_zone(realm, zonegroup, rgw_spec.rgw_zone,
False, # secondary zone
- access_key, secret, endpoints=rgw_spec.zone_endpoints)
+ access_key, secret, endpoints=rgw_spec.zone_endpoints,
+ tier_type=tier_type, master_zone_name=master_zone_name)
# Adding a retry limit for period update in case the default 10s timeout is not sufficient
rgw_limit = 0