From 2c1a7b1bbfd14aa787eb86dac35d99a942e2a897 Mon Sep 17 00:00:00 2001 From: Tatjana Dehler Date: Mon, 17 Dec 2018 12:26:24 +0100 Subject: [PATCH] mgr/dashboard: add validators to osdRecvSpeedForm Fixes: https://tracker.ceph.com/issues/37436 Signed-off-by: Tatjana Dehler --- .../osd-recv-speed-modal.component.html | 12 +++++ .../osd-recv-speed-modal.component.spec.ts | 51 +++++++++++++++++++ .../osd-recv-speed-modal.component.ts | 47 +++++++++++++++-- .../frontend/src/locale/messages.xlf | 22 +++++++- 4 files changed, 126 insertions(+), 6 deletions(-) diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html index 884a1c56daef1..4429882b78cc7 100755 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html @@ -65,6 +65,18 @@ *ngIf="osdRecvSpeedForm.getValue('customizePriority') && osdRecvSpeedForm.showError(attr.key, formDir, 'required')" i18n>This field is required! + {{ attr.value.patternHelpText }} + The entered value is too high! It must not be greater than {{ attr.value.maxValue }}. + The entered value is too low! It must not be lower than {{ attr.value.minValue }}. diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.spec.ts index 7c679091a8715..bee7768fd78f7 100755 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.spec.ts @@ -194,4 +194,55 @@ describe('OsdRecvSpeedModalComponent', () => { }); }); }); + + describe('setValidators', () => { + const configOptions = [ + { + name: 'osd_max_backfills', + type: 'uint' + }, + { + name: 'osd_recovery_max_active', + type: 'uint' + }, + { + name: 'osd_recovery_max_single_start', + type: 'uint' + }, + { + name: 'osd_recovery_sleep', + type: 'float' + } + ]; + + it('should set needed validators for config option', () => { + component.setValidators(configOptions); + configOptions.forEach((configOption) => { + const control = component.osdRecvSpeedForm.controls[configOption.name]; + + if (configOption.type === 'float') { + expect(component.priorityAttrs[configOption.name].patternHelpText).toBe( + 'The entered value needs to be a number or decimal.' + ); + } else { + expect(component.priorityAttrs[configOption.name].minValue).toBe(0); + expect(component.priorityAttrs[configOption.name].patternHelpText).toBe( + 'The entered value needs to be an unsigned number.' + ); + + control.setValue(-1); + expect(control.hasError('min')).toBeTruthy(); + } + + control.setValue(null); + expect(control.hasError('required')).toBeTruthy(); + control.setValue('E'); + expect(control.hasError('pattern')).toBeTruthy(); + control.setValue(3); + expect(control.hasError('required')).toBeFalsy(); + expect(control.hasError('min')).toBeFalsy(); + expect(control.hasError('pattern')).toBeFalsy(); + }); + }); + }); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts index 860ad1bcf331d..12dc31a0dcc88 100755 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts @@ -12,6 +12,7 @@ import { OsdService } from '../../../../shared/api/osd.service'; import { NotificationType } from '../../../../shared/enum/notification-type.enum'; import { CdFormGroup } from '../../../../shared/forms/cd-form-group'; import { NotificationService } from '../../../../shared/services/notification.service'; +import { ConfigOptionTypes } from '../../configuration/configuration-form/configuration-form.types'; @Component({ selector: 'cd-osd-recv-speed-modal', @@ -38,19 +39,31 @@ export class OsdRecvSpeedModalComponent implements OnInit { this.priorityAttrs = { osd_max_backfills: { text: this.i18n('Max Backfills'), - desc: '' + desc: '', + patternHelpText: '', + maxValue: undefined, + minValue: undefined }, osd_recovery_max_active: { text: this.i18n('Recovery Max Active'), - desc: '' + desc: '', + patternHelpText: '', + maxValue: undefined, + minValue: undefined }, osd_recovery_max_single_start: { text: this.i18n('Recovery Max Single Start'), - desc: '' + desc: '', + patternHelpText: '', + maxValue: undefined, + minValue: undefined }, osd_recovery_sleep: { text: this.i18n('Recovery Sleep'), - desc: '' + desc: '', + patternHelpText: '', + maxValue: undefined, + minValue: undefined } }; @@ -91,6 +104,7 @@ export class OsdRecvSpeedModalComponent implements OnInit { this.setPriority(priority); }); this.setDescription(resp.configOptions); + this.setValidators(resp.configOptions); }); } @@ -144,6 +158,28 @@ export class OsdRecvSpeedModalComponent implements OnInit { }); } + setValidators(configOptions: Array) { + configOptions.forEach((configOption) => { + const typeValidators = ConfigOptionTypes.getTypeValidators(configOption); + if (typeValidators) { + typeValidators.validators.push(Validators.required); + + if ('max' in typeValidators && typeValidators.max !== '') { + this.priorityAttrs[configOption.name].maxValue = typeValidators.max; + } + + if ('min' in typeValidators && typeValidators.min !== '') { + this.priorityAttrs[configOption.name].minValue = typeValidators.min; + } + + this.priorityAttrs[configOption.name].patternHelpText = typeValidators.patternHelpText; + this.osdRecvSpeedForm.controls[configOption.name].setValidators(typeValidators.validators); + } else { + this.osdRecvSpeedForm.controls[configOption.name].setValidators(Validators.required); + } + }); + } + onCustomizePriorityChange() { if (this.osdRecvSpeedForm.getValue('customizePriority')) { const values = {}; @@ -169,6 +205,9 @@ export class OsdRecvSpeedModalComponent implements OnInit { _.find(this.priorities, (p) => { return p.name === selectedPriorityName; }) || this.priorities[0]; + // Uncheck the 'Customize priority values' checkbox. + this.osdRecvSpeedForm.get('customizePriority').setValue(false); + // Set the priority profile values. this.setPriority(selectedPriority); } diff --git a/src/pybind/mgr/dashboard/frontend/src/locale/messages.xlf b/src/pybind/mgr/dashboard/frontend/src/locale/messages.xlf index 8c73162c6732d..d7a8c9179d497 100644 --- a/src/pybind/mgr/dashboard/frontend/src/locale/messages.xlf +++ b/src/pybind/mgr/dashboard/frontend/src/locale/messages.xlf @@ -863,7 +863,7 @@ app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html - 79 + 91 app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html @@ -919,7 +919,7 @@ app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html - 75 + 87 app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html @@ -985,6 +985,24 @@ app/ceph/pool/pool-form/pool-form.component.html 95 + + + + app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html + 71 + + + The entered value is too high! It must not be greater than . + + app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html + 75 + + + The entered value is too low! It must not be lower than . + + app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html + 79 + Reweight OSD -- 2.39.5