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';
12 ALLOW_READ_THROUGH_TEXT,
15 MULTIPART_MIN_PART_TEXT,
16 MULTIPART_SYNC_THRESHOLD_TEXT,
19 RETAIN_HEAD_OBJECT_TEXT,
22 TARGET_ACCESS_KEY_TEXT,
26 TARGET_SECRET_KEY_TEXT,
30 } from '../models/rgw-storage-class.model';
31 import { NotificationType } from '~/app/shared/enum/notification-type.enum';
32 import { NotificationService } from '~/app/shared/services/notification.service';
35 selector: 'cd-rgw-storage-class-form',
36 templateUrl: './rgw-storage-class-form.component.html',
37 styleUrls: ['./rgw-storage-class-form.component.scss']
39 export class RgwStorageClassFormComponent extends CdForm implements OnInit {
40 storageClassForm: CdFormGroup;
44 targetPathText: string;
45 targetEndpointText: string;
46 targetRegionText: string;
47 showAdvanced: boolean = false;
48 defaultZoneGroup: string;
49 zonegroupNames: ZoneGroup[];
50 placementTargets: string[] = [];
51 multipartMinPartText: string;
52 multipartSyncThreholdText: string;
53 selectedZoneGroup: string;
54 defaultZonegroup: ZoneGroup;
55 zoneGroupDetails: ZoneGroupDetails;
56 targetSecretKeyText: string;
57 targetAccessKeyText: string;
58 retainHeadObjectText: string;
59 storageClassInfo: StorageClass;
60 tierTargetInfo: TierTarget;
61 allowReadThroughText: string;
62 allowReadThrough: boolean = false;
65 public actionLabels: ActionLabelsI18n,
66 private formBuilder: CdFormBuilder,
67 private notificationService: NotificationService,
68 private rgwStorageService: RgwStorageClassService,
69 private rgwZoneGroupService: RgwZonegroupService,
70 private router: Router,
71 private route: ActivatedRoute
74 this.resource = $localize`Tiering Storage Class`;
75 this.editing = this.router.url.startsWith(`/rgw/tiering/${URLVerbs.EDIT}`);
76 this.action = this.editing ? this.actionLabels.EDIT : this.actionLabels.CREATE;
80 this.multipartMinPartText = MULTIPART_MIN_PART_TEXT;
81 this.multipartSyncThreholdText = MULTIPART_SYNC_THRESHOLD_TEXT;
82 this.targetPathText = TARGET_PATH_TEXT;
83 this.targetRegionText = TARGET_REGION_TEXT;
84 this.targetEndpointText = TARGET_ENDPOINT_TEXT;
85 this.targetAccessKeyText = TARGET_ACCESS_KEY_TEXT;
86 this.targetSecretKeyText = TARGET_SECRET_KEY_TEXT;
87 this.retainHeadObjectText = RETAIN_HEAD_OBJECT_TEXT;
88 this.allowReadThroughText = ALLOW_READ_THROUGH_TEXT;
93 this.route.params.subscribe((params: StorageClass) => {
94 this.storageClassInfo = params;
96 this.rgwStorageService
97 .getPlacement_target(this.storageClassInfo.placement_target)
98 .subscribe((placementTargetInfo: PlacementTarget) => {
99 this.tierTargetInfo = this.getTierTargetByStorageClass(
101 this.storageClassInfo.storage_class
103 let response = this.tierTargetInfo.val.s3;
104 this.storageClassForm.get('zonegroup').disable();
105 this.storageClassForm.get('placement_target').disable();
106 this.storageClassForm.get('storage_class').disable();
107 this.storageClassForm.get('zonegroup').setValue(this.storageClassInfo.zonegroup_name);
108 this.storageClassForm.get('region').setValue(response.region);
109 this.storageClassForm
110 .get('placement_target')
111 .setValue(this.storageClassInfo.placement_target);
112 this.storageClassForm.get('endpoint').setValue(response.endpoint);
113 this.storageClassForm.get('storage_class').setValue(this.storageClassInfo.storage_class);
114 this.storageClassForm.get('access_key').setValue(response.access_key);
115 this.storageClassForm.get('secret_key').setValue(response.secret);
116 this.storageClassForm.get('target_path').setValue(response.target_path);
117 this.storageClassForm
118 .get('retain_head_object')
119 .setValue(this.tierTargetInfo?.val?.retain_head_object || false);
120 this.storageClassForm
121 .get('multipart_sync_threshold')
122 .setValue(response.multipart_sync_threshold || '');
123 this.storageClassForm
124 .get('multipart_min_part_size')
125 .setValue(response.multipart_min_part_size || '');
126 this.storageClassForm
127 .get('allow_read_through')
128 .setValue(this.tierTargetInfo?.val?.allow_read_through || false);
131 this.storageClassForm.get('allow_read_through').valueChanges.subscribe((value) => {
132 this.onAllowReadThroughChange(value);
137 this.storageClassForm = this.formBuilder.group({
138 storage_class: new FormControl('', {
139 validators: [Validators.required]
141 zonegroup: new FormControl(this.selectedZoneGroup, {
142 validators: [Validators.required]
144 region: new FormControl('', {
145 validators: [Validators.required]
147 placement_target: new FormControl('', {
148 validators: [Validators.required]
150 endpoint: new FormControl(null, {
151 validators: [Validators.required]
153 access_key: new FormControl(null, Validators.required),
154 secret_key: new FormControl(null, Validators.required),
155 target_path: new FormControl('', {
156 validators: [Validators.required]
158 retain_head_object: new FormControl(true),
159 multipart_sync_threshold: new FormControl(33554432),
160 multipart_min_part_size: new FormControl(33554432),
161 allow_read_through: new FormControl(false)
165 loadZoneGroup(): Promise<void> {
166 return new Promise((resolve, reject) => {
167 this.rgwZoneGroupService.getAllZonegroupsInfo().subscribe(
168 (data: ZoneGroupDetails) => {
169 this.zoneGroupDetails = data;
170 this.zonegroupNames = [];
171 this.placementTargets = [];
172 if (data.zonegroups && data.zonegroups.length > 0) {
173 this.zonegroupNames = data.zonegroups.map((zoneGroup: ZoneGroup) => {
180 this.defaultZonegroup = this.zonegroupNames.find(
181 (zonegroups: ZoneGroup) => zonegroups.id === data.default_zonegroup
184 this.storageClassForm.get('zonegroup').setValue(this.defaultZonegroup.name);
185 this.onZonegroupChange();
188 (error) => reject(error)
193 onZonegroupChange() {
194 const zoneGroupControl = this.storageClassForm.get('zonegroup').value;
195 const selectedZoneGroup = this.zoneGroupDetails.zonegroups.find(
196 (zonegroup) => zonegroup.name === zoneGroupControl
198 const defaultPlacementTarget = selectedZoneGroup.placement_targets.find(
199 (target: Target) => target.name === DEFAULT_PLACEMENT
201 if (selectedZoneGroup) {
202 const placementTargetNames = selectedZoneGroup.placement_targets.map(
203 (target: Target) => target.name
205 this.placementTargets = placementTargetNames;
207 if (defaultPlacementTarget && !this.editing) {
208 this.storageClassForm.get('placement_target').setValue(defaultPlacementTarget.name);
210 this.storageClassForm
211 .get('placement_target')
212 .setValue(this.storageClassInfo.placement_target);
217 const component = this;
218 const requestModel = this.buildRequest();
219 const storageclassName = this.storageClassForm.get('storage_class').value;
221 this.rgwStorageService.editStorageClass(requestModel).subscribe(
223 this.notificationService.show(
224 NotificationType.success,
225 $localize`Updated Storage Class '${storageclassName}'`
230 component.storageClassForm.setErrors({ cdSubmitButton: true });
234 this.rgwStorageService.createStorageClass(requestModel).subscribe(
236 this.notificationService.show(
237 NotificationType.success,
238 $localize`Created Storage Class '${storageclassName}'`
243 component.storageClassForm.setErrors({ cdSubmitButton: true });
250 this.router.navigate([`rgw/tiering`]);
253 getTierTargetByStorageClass(placementTargetInfo: PlacementTarget, storageClass: string) {
254 const tierTarget = placementTargetInfo.tier_targets.find(
255 (target: TierTarget) => target.val.storage_class === storageClass
260 onAllowReadThroughChange(checked: boolean): void {
261 this.allowReadThrough = checked;
262 if (this.allowReadThrough) {
263 this.storageClassForm.get('retain_head_object')?.setValue(true);
264 this.storageClassForm.get('retain_head_object')?.disable();
266 this.storageClassForm.get('retain_head_object')?.enable();
271 const rawFormValue = _.cloneDeep(this.storageClassForm.value);
272 const zoneGroup = this.storageClassForm.get('zonegroup').value;
273 const storageClass = this.storageClassForm.get('storage_class').value;
274 const placementId = this.storageClassForm.get('placement_target').value;
275 const headObject = this.storageClassForm.get('retain_head_object').value;
276 const requestModel: RequestModel = {
277 zone_group: zoneGroup,
281 placement_id: placementId,
282 storage_class: storageClass,
283 tier_type: CLOUD_TIER,
285 endpoint: rawFormValue.endpoint,
286 access_key: rawFormValue.access_key,
287 secret: rawFormValue.secret_key,
288 target_path: rawFormValue.target_path,
289 retain_head_object: headObject,
290 allow_read_through: rawFormValue.allow_read_through,
291 region: rawFormValue.region,
292 multipart_sync_threshold: rawFormValue.multipart_sync_threshold,
293 multipart_min_part_size: rawFormValue.multipart_min_part_size