9 } from '@angular/core';
10 import { Router } from '@angular/router';
12 import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
13 import _ from 'lodash';
14 import { forkJoin, Subscription } from 'rxjs';
15 import { finalize } from 'rxjs/operators';
17 import { ClusterService } from '~/app/shared/api/cluster.service';
18 import { HostService } from '~/app/shared/api/host.service';
19 import { OsdService } from '~/app/shared/api/osd.service';
20 import { ConfirmationModalComponent } from '~/app/shared/components/confirmation-modal/confirmation-modal.component';
21 import { ActionLabelsI18n, AppConstants, URLVerbs } from '~/app/shared/constants/app.constants';
22 import { NotificationType } from '~/app/shared/enum/notification-type.enum';
23 import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
24 import { FinishedTask } from '~/app/shared/models/finished-task';
25 import { DeploymentOptions } from '~/app/shared/models/osd-deployment-options';
26 import { Permissions } from '~/app/shared/models/permissions';
27 import { WizardStepModel } from '~/app/shared/models/wizard-steps';
28 import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
29 import { ModalService } from '~/app/shared/services/modal.service';
30 import { NotificationService } from '~/app/shared/services/notification.service';
31 import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
32 import { WizardStepsService } from '~/app/shared/services/wizard-steps.service';
33 import { DriveGroup } from '../osd/osd-form/drive-group.model';
36 selector: 'cd-create-cluster',
37 templateUrl: './create-cluster.component.html',
38 styleUrls: ['./create-cluster.component.scss']
40 export class CreateClusterComponent implements OnInit, OnDestroy {
41 @ViewChild('skipConfirmTpl', { static: true })
42 skipConfirmTpl: TemplateRef<any>;
43 currentStep: WizardStepModel;
44 currentStepSub: Subscription;
45 permissions: Permissions;
46 projectConstants: typeof AppConstants = AppConstants;
47 stepTitles = ['Add Hosts', 'Create OSDs', 'Create Services', 'Review'];
48 startClusterCreation = false;
49 observables: any = [];
50 modalRef: NgbModalRef;
51 driveGroup = new DriveGroup();
52 driveGroups: Object[] = [];
53 deploymentOption: DeploymentOptions;
55 simpleDeployment = true;
56 stepsToSkip: { [steps: string]: boolean } = {};
59 submitAction = new EventEmitter();
62 private authStorageService: AuthStorageService,
63 private wizardStepsService: WizardStepsService,
64 private router: Router,
65 private hostService: HostService,
66 private notificationService: NotificationService,
67 private actionLabels: ActionLabelsI18n,
68 private clusterService: ClusterService,
69 private modalService: ModalService,
70 private taskWrapper: TaskWrapperService,
71 private osdService: OsdService
73 this.permissions = this.authStorageService.getPermissions();
74 this.currentStepSub = this.wizardStepsService
76 .subscribe((step: WizardStepModel) => {
77 this.currentStep = step;
79 this.currentStep.stepIndex = 1;
83 this.osdService.getDeploymentOptions().subscribe((options) => {
84 this.deploymentOption = options;
85 this.selectedOption = { option: options.recommended_option, encrypted: false };
88 this.stepTitles.forEach((stepTitle) => {
89 this.stepsToSkip[stepTitle] = false;
94 this.startClusterCreation = true;
97 skipClusterCreation() {
98 const modalVariables = {
99 titleText: $localize`Warning`,
100 buttonText: $localize`Continue`,
102 bodyTpl: this.skipConfirmTpl,
105 this.clusterService.updateStatus('POST_INSTALLED').subscribe({
106 error: () => this.modalRef.close(),
108 this.notificationService.show(
109 NotificationType.info,
110 $localize`Cluster expansion skipped by user`
112 this.router.navigate(['/dashboard']);
113 this.modalRef.close();
118 this.modalRef = this.modalService.show(ConfirmationModalComponent, modalVariables);
122 if (!this.stepsToSkip['Add Hosts']) {
123 const hostContext = new CdTableFetchDataContext(() => undefined);
124 this.hostService.list(hostContext.toParams(), 'false').subscribe((hosts) => {
125 hosts.forEach((host) => {
126 const index = host['labels'].indexOf('_no_schedule', 0);
128 host['labels'].splice(index, 1);
129 this.observables.push(this.hostService.update(host['hostname'], true, host['labels']));
132 forkJoin(this.observables)
135 this.clusterService.updateStatus('POST_INSTALLED').subscribe(() => {
136 this.notificationService.show(
137 NotificationType.success,
138 $localize`Cluster expansion was successful`
140 this.router.navigate(['/dashboard']);
145 error: (error) => error.preventDefault()
150 if (!this.stepsToSkip['Create OSDs']) {
151 if (this.driveGroup) {
152 const user = this.authStorageService.getUsername();
153 this.driveGroup.setName(`dashboard-${user}-${_.now()}`);
154 this.driveGroups.push(this.driveGroup.spec);
157 if (this.simpleDeployment) {
158 const title = this.deploymentOption?.options[this.selectedOption['option']].title;
159 const trackingId = $localize`${title} deployment`;
161 .wrapTaskAroundCall({
162 task: new FinishedTask('osd/' + URLVerbs.CREATE, {
163 tracking_id: trackingId
165 call: this.osdService.create([this.selectedOption], trackingId, 'predefined')
168 error: (error) => error.preventDefault(),
170 this.submitAction.emit();
174 if (this.osdService.osdDevices['totalDevices'] > 0) {
175 this.driveGroup.setFeature('encrypted', this.selectedOption['encrypted']);
176 const trackingId = _.join(_.map(this.driveGroups, 'service_id'), ', ');
178 .wrapTaskAroundCall({
179 task: new FinishedTask('osd/' + URLVerbs.CREATE, {
180 tracking_id: trackingId
182 call: this.osdService.create(this.driveGroups, trackingId)
185 error: (error) => error.preventDefault(),
187 this.submitAction.emit();
188 this.osdService.osdDevices = [];
196 setDriveGroup(driveGroup: DriveGroup) {
197 this.driveGroup = driveGroup;
200 setDeploymentOptions(option: object) {
201 this.selectedOption = option;
204 setDeploymentMode(mode: boolean) {
205 this.simpleDeployment = mode;
209 if (!this.wizardStepsService.isLastStep()) {
210 this.wizardStepsService.getCurrentStep().subscribe((step: WizardStepModel) => {
211 this.currentStep = step;
213 this.wizardStepsService.moveToNextStep();
220 if (!this.wizardStepsService.isFirstStep()) {
221 this.wizardStepsService.moveToPreviousStep();
223 this.router.navigate(['/dashboard']);
228 const stepTitle = this.stepTitles[this.currentStep.stepIndex - 1];
229 this.stepsToSkip[stepTitle] = true;
233 showSubmitButtonLabel() {
234 return !this.wizardStepsService.isLastStep()
235 ? this.actionLabels.NEXT
236 : $localize`Expand Cluster`;
239 showCancelButtonLabel() {
240 return !this.wizardStepsService.isFirstStep()
241 ? this.actionLabels.BACK
242 : this.actionLabels.CANCEL;
245 ngOnDestroy(): void {
246 this.currentStepSub.unsubscribe();