]> git.apps.os.sepia.ceph.com Git - ceph.git/blob
ed4677035f3216bc0c0c0d72adce79cb53a315b2
[ceph.git] /
1 import { Component, OnInit } from '@angular/core';
2 import { FormControl, Validators } from '@angular/forms';
3 import { ActionLabelsI18n } 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 { 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';
11 import {
12   CLOUD_TIER,
13   DEFAULT_PLACEMENT,
14   RequestModel,
15   Target,
16   ZoneGroup,
17   ZoneGroupDetails
18 } from '../models/rgw-storage-class.model';
19 import { NotificationType } from '~/app/shared/enum/notification-type.enum';
20 import { NotificationService } from '~/app/shared/services/notification.service';
21
22 @Component({
23   selector: 'cd-rgw-storage-class-form',
24   templateUrl: './rgw-storage-class-form.component.html',
25   styleUrls: ['./rgw-storage-class-form.component.scss']
26 })
27 export class RgwStorageClassFormComponent extends CdForm implements OnInit {
28   storageClassForm: CdFormGroup;
29   action: string;
30   resource: string;
31   targetPathText: string;
32   targetEndpointText: string;
33   targetRegionText: string;
34   showAdvanced: boolean = false;
35   defaultZoneGroup: string;
36   zonegroupNames: ZoneGroup[];
37   placementTargets: string[] = [];
38   multipartMinPartText: string;
39   multipartSyncThreholdText: string;
40   selectedZoneGroup: string;
41   defaultZonegroup: ZoneGroup;
42   zoneGroupDeatils: ZoneGroupDetails;
43   targetSecretKeyText: string;
44   targetAccessKeyText: string;
45   retainHeadObjectText: string;
46
47   constructor(
48     public actionLabels: ActionLabelsI18n,
49     private formBuilder: CdFormBuilder,
50     private notificationService: NotificationService,
51     private rgwStorageService: RgwStorageClassService,
52     private rgwZoneGroupService: RgwZonegroupService,
53     private router: Router
54   ) {
55     super();
56     this.resource = $localize`Tiering Storage Class`;
57   }
58
59   ngOnInit() {
60     this.multipartMinPartText =
61       'It specifies that objects this size or larger are transitioned to the cloud using multipart upload.';
62     this.multipartSyncThreholdText =
63       'It specifies the minimum part size to use when transitioning objects using multipart upload.';
64     this.targetPathText =
65       'Target Path refers to the storage location (e.g., bucket or container) in the cloud where data will be stored.';
66     this.targetRegionText = 'The region of the remote cloud service where storage is located.';
67     this.targetEndpointText = 'The URL endpoint of the remote cloud service for accessing storage.';
68     this.targetAccessKeyText =
69       "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.";
70
71     this.targetSecretKeyText =
72       "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.";
73     this.retainHeadObjectText =
74       'Retain object metadata after transition to the cloud (default: deleted).';
75     this.action = this.actionLabels.CREATE;
76     this.createForm();
77     this.loadZoneGroup();
78   }
79
80   createForm() {
81     this.storageClassForm = this.formBuilder.group({
82       storage_class: new FormControl('', {
83         validators: [Validators.required]
84       }),
85       zonegroup: new FormControl(this.selectedZoneGroup, {
86         validators: [Validators.required]
87       }),
88       region: new FormControl('', {
89         validators: [Validators.required]
90       }),
91       placement_target: new FormControl('', {
92         validators: [Validators.required]
93       }),
94       endpoint: new FormControl(null, {
95         validators: [Validators.required]
96       }),
97       access_key: new FormControl(null, Validators.required),
98       secret_key: new FormControl(null, Validators.required),
99       target_path: new FormControl('', {
100         validators: [Validators.required]
101       }),
102       retain_head_object: new FormControl(false),
103       multipart_sync_threshold: new FormControl(33554432),
104       multipart_min_part_size: new FormControl(33554432)
105     });
106   }
107
108   loadZoneGroup(): Promise<void> {
109     return new Promise((resolve, reject) => {
110       this.rgwZoneGroupService.getAllZonegroupsInfo().subscribe(
111         (data: ZoneGroupDetails) => {
112           this.zoneGroupDeatils = data;
113           this.zonegroupNames = [];
114           this.placementTargets = [];
115           if (data.zonegroups && data.zonegroups.length > 0) {
116             this.zonegroupNames = data.zonegroups.map((zoneGroup: ZoneGroup) => {
117               return {
118                 id: zoneGroup.id,
119                 name: zoneGroup.name
120               };
121             });
122           }
123           this.defaultZonegroup = this.zonegroupNames.find(
124             (zonegroups: ZoneGroup) => zonegroups.id === data.default_zonegroup
125           );
126
127           this.storageClassForm.get('zonegroup').setValue(this.defaultZonegroup.name);
128           this.onZonegroupChange();
129           resolve();
130         },
131         (error) => reject(error)
132       );
133     });
134   }
135
136   onZonegroupChange() {
137     const zoneGroupControl = this.storageClassForm.get('zonegroup').value;
138     const selectedZoneGroup = this.zoneGroupDeatils.zonegroups.find(
139       (zonegroup) => zonegroup.name === zoneGroupControl
140     );
141     const defaultPlacementTarget = selectedZoneGroup.placement_targets.find(
142       (target: Target) => target.name === DEFAULT_PLACEMENT
143     );
144     if (selectedZoneGroup) {
145       const placementTargetNames = selectedZoneGroup.placement_targets.map(
146         (target: Target) => target.name
147       );
148       this.placementTargets = placementTargetNames;
149     }
150     if (defaultPlacementTarget) {
151       this.storageClassForm.get('placement_target').setValue(defaultPlacementTarget.name);
152     }
153   }
154
155   submitAction() {
156     const component = this;
157     const requestModel = this.buildRequest();
158     const storageclassName = this.storageClassForm.get('storage_class').value;
159     this.rgwStorageService.createStorageClass(requestModel).subscribe(
160       () => {
161         this.notificationService.show(
162           NotificationType.success,
163           $localize`Created Storage Class '${storageclassName}'`
164         );
165         this.goToListView();
166       },
167       () => {
168         component.storageClassForm.setErrors({ cdSubmitButton: true });
169       }
170     );
171   }
172
173   goToListView() {
174     this.router.navigate([`rgw/tiering`]);
175   }
176
177   buildRequest() {
178     const rawFormValue = _.cloneDeep(this.storageClassForm.value);
179     const requestModel: RequestModel = {
180       zone_group: rawFormValue.zonegroup,
181       placement_targets: [
182         {
183           tags: [],
184           placement_id: rawFormValue.placement_target,
185           storage_class: rawFormValue.storage_class,
186           tier_type: CLOUD_TIER,
187           tier_config: {
188             endpoint: rawFormValue.endpoint,
189             access_key: rawFormValue.access_key,
190             secret: rawFormValue.secret_key,
191             target_path: rawFormValue.target_path,
192             retain_head_object: rawFormValue.retain_head_object,
193             region: rawFormValue.region,
194             multipart_sync_threshold: rawFormValue.multipart_sync_threshold,
195             multipart_min_part_size: rawFormValue.multipart_min_part_size
196           }
197         }
198       ]
199     };
200     return requestModel;
201   }
202 }