1 import { Component, OnInit } from '@angular/core';
2 import { FormControl, Validators } from '@angular/forms';
3 import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants';
4 import { CdForm } from '~/app/shared/forms/cd-form';
5 import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
6 import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
7 import _ from 'lodash';
8 import { ActivatedRoute, Router } from '@angular/router';
9 import { RgwStorageClassService } from '~/app/shared/api/rgw-storage-class.service';
10 import { RgwZonegroupService } from '~/app/shared/api/rgw-zonegroup.service';
21 } from '../models/rgw-storage-class.model';
22 import { NotificationType } from '~/app/shared/enum/notification-type.enum';
23 import { NotificationService } from '~/app/shared/services/notification.service';
26 selector: 'cd-rgw-storage-class-form',
27 templateUrl: './rgw-storage-class-form.component.html',
28 styleUrls: ['./rgw-storage-class-form.component.scss']
30 export class RgwStorageClassFormComponent extends CdForm implements OnInit {
31 storageClassForm: CdFormGroup;
35 targetPathText: string;
36 targetEndpointText: string;
37 targetRegionText: string;
38 showAdvanced: boolean = false;
39 defaultZoneGroup: string;
40 zonegroupNames: ZoneGroup[];
41 placementTargets: string[] = [];
42 multipartMinPartText: string;
43 multipartSyncThreholdText: string;
44 selectedZoneGroup: string;
45 defaultZonegroup: ZoneGroup;
46 zoneGroupDetails: ZoneGroupDetails;
47 targetSecretKeyText: string;
48 targetAccessKeyText: string;
49 retainHeadObjectText: string;
50 storageClassInfo: StorageClass;
51 tierTargetInfo: TierTarget;
54 public actionLabels: ActionLabelsI18n,
55 private formBuilder: CdFormBuilder,
56 private notificationService: NotificationService,
57 private rgwStorageService: RgwStorageClassService,
58 private rgwZoneGroupService: RgwZonegroupService,
59 private router: Router,
60 private route: ActivatedRoute
63 this.resource = $localize`Tiering Storage Class`;
64 this.editing = this.router.url.startsWith(`/rgw/tiering/${URLVerbs.EDIT}`);
65 this.action = this.editing ? this.actionLabels.EDIT : this.actionLabels.CREATE;
69 this.multipartMinPartText =
70 'It specifies that objects this size or larger are transitioned to the cloud using multipart upload.';
71 this.multipartSyncThreholdText =
72 'It specifies the minimum part size to use when transitioning objects using multipart upload.';
74 'Target Path refers to the storage location (e.g., bucket or container) in the cloud where data will be stored.';
75 this.targetRegionText = 'The region of the remote cloud service where storage is located.';
76 this.targetEndpointText = 'The URL endpoint of the remote cloud service for accessing storage.';
77 this.targetAccessKeyText =
78 "To view or copy your access key, go to your cloud service's user management or credentials section, find your user profile, and locate the access key. You can view and copy the key by following the instructions provided.";
80 this.targetSecretKeyText =
81 "To view or copy your secret key, go to your cloud service's user management or credentials section, find your user profile, and locate the access key. You can view and copy the key by following the instructions provided.";
82 this.retainHeadObjectText =
83 'Retain object metadata after transition to the cloud (default: deleted).';
88 this.route.params.subscribe((params: StorageClass) => {
89 this.storageClassInfo = params;
91 this.rgwStorageService
92 .getPlacement_target(this.storageClassInfo.placement_target)
93 .subscribe((placementTargetInfo: PlacementTarget) => {
94 this.tierTargetInfo = this.getTierTargetByStorageClass(
96 this.storageClassInfo.storage_class
98 let response = this.tierTargetInfo.val.s3;
99 this.storageClassForm.get('zonegroup').disable();
100 this.storageClassForm.get('placement_target').disable();
101 this.storageClassForm.get('storage_class').disable();
102 this.storageClassForm.get('zonegroup').setValue(this.storageClassInfo.zonegroup_name);
103 this.storageClassForm.get('region').setValue(response.region);
104 this.storageClassForm
105 .get('placement_target')
106 .setValue(this.storageClassInfo.placement_target);
107 this.storageClassForm.get('endpoint').setValue(response.endpoint);
108 this.storageClassForm.get('storage_class').setValue(this.storageClassInfo.storage_class);
109 this.storageClassForm.get('access_key').setValue(response.access_key);
110 this.storageClassForm.get('secret_key').setValue(response.access_key);
111 this.storageClassForm.get('target_path').setValue(response.target_path);
112 this.storageClassForm
113 .get('retain_head_object')
114 .setValue(response.retain_head_object || false);
115 this.storageClassForm
116 .get('multipart_sync_threshold')
117 .setValue(response.multipart_sync_threshold || '');
118 this.storageClassForm
119 .get('multipart_min_part_size')
120 .setValue(response.multipart_min_part_size || '');
126 this.storageClassForm = this.formBuilder.group({
127 storage_class: new FormControl('', {
128 validators: [Validators.required]
130 zonegroup: new FormControl(this.selectedZoneGroup, {
131 validators: [Validators.required]
133 region: new FormControl('', {
134 validators: [Validators.required]
136 placement_target: new FormControl('', {
137 validators: [Validators.required]
139 endpoint: new FormControl(null, {
140 validators: [Validators.required]
142 access_key: new FormControl(null, Validators.required),
143 secret_key: new FormControl(null, Validators.required),
144 target_path: new FormControl('', {
145 validators: [Validators.required]
147 retain_head_object: new FormControl(false),
148 multipart_sync_threshold: new FormControl(33554432),
149 multipart_min_part_size: new FormControl(33554432)
153 loadZoneGroup(): Promise<void> {
154 return new Promise((resolve, reject) => {
155 this.rgwZoneGroupService.getAllZonegroupsInfo().subscribe(
156 (data: ZoneGroupDetails) => {
157 this.zoneGroupDetails = data;
158 this.zonegroupNames = [];
159 this.placementTargets = [];
160 if (data.zonegroups && data.zonegroups.length > 0) {
161 this.zonegroupNames = data.zonegroups.map((zoneGroup: ZoneGroup) => {
168 this.defaultZonegroup = this.zonegroupNames.find(
169 (zonegroups: ZoneGroup) => zonegroups.id === data.default_zonegroup
172 this.storageClassForm.get('zonegroup').setValue(this.defaultZonegroup.name);
173 this.onZonegroupChange();
176 (error) => reject(error)
181 onZonegroupChange() {
182 const zoneGroupControl = this.storageClassForm.get('zonegroup').value;
183 const selectedZoneGroup = this.zoneGroupDetails.zonegroups.find(
184 (zonegroup) => zonegroup.name === zoneGroupControl
186 const defaultPlacementTarget = selectedZoneGroup.placement_targets.find(
187 (target: Target) => target.name === DEFAULT_PLACEMENT
189 if (selectedZoneGroup) {
190 const placementTargetNames = selectedZoneGroup.placement_targets.map(
191 (target: Target) => target.name
193 this.placementTargets = placementTargetNames;
195 if (defaultPlacementTarget && !this.editing) {
196 this.storageClassForm.get('placement_target').setValue(defaultPlacementTarget.name);
198 this.storageClassForm
199 .get('placement_target')
200 .setValue(this.storageClassInfo.placement_target);
205 const component = this;
206 const requestModel = this.buildRequest();
207 const storageclassName = this.storageClassForm.get('storage_class').value;
209 this.rgwStorageService.editStorageClass(requestModel).subscribe(
211 this.notificationService.show(
212 NotificationType.success,
213 $localize`Updated Storage Class '${storageclassName}'`
218 component.storageClassForm.setErrors({ cdSubmitButton: true });
222 this.rgwStorageService.createStorageClass(requestModel).subscribe(
224 this.notificationService.show(
225 NotificationType.success,
226 $localize`Created Storage Class '${storageclassName}'`
231 component.storageClassForm.setErrors({ cdSubmitButton: true });
238 this.router.navigate([`rgw/tiering`]);
241 getTierTargetByStorageClass(placementTargetInfo: PlacementTarget, storageClass: string) {
242 const tierTarget = placementTargetInfo.tier_targets.find(
243 (target: TierTarget) => target.val.storage_class === storageClass
249 const rawFormValue = _.cloneDeep(this.storageClassForm.value);
250 const zoneGroup = this.storageClassForm.get('zonegroup').value;
251 const storageClass = this.storageClassForm.get('storage_class').value;
252 const placementId = this.storageClassForm.get('placement_target').value;
253 const requestModel: RequestModel = {
254 zone_group: zoneGroup,
258 placement_id: placementId,
259 storage_class: storageClass,
260 tier_type: CLOUD_TIER,
262 endpoint: rawFormValue.endpoint,
263 access_key: rawFormValue.access_key,
264 secret: rawFormValue.secret_key,
265 target_path: rawFormValue.target_path,
266 retain_head_object: rawFormValue.retain_head_object,
267 region: rawFormValue.region,
268 multipart_sync_threshold: rawFormValue.multipart_sync_threshold,
269 multipart_min_part_size: rawFormValue.multipart_min_part_size