From 97c57adf8565756dbf24f3c46ed3916303903fb7 Mon Sep 17 00:00:00 2001 From: Sarthak0702 Date: Fri, 11 Feb 2022 01:20:42 +0530 Subject: [PATCH 1/2] mgr/dashboard: dashboard turns telemetry off when configuring report Signed-off-by: Sarthak0702 --- .../telemetry/telemetry.component.spec.ts | 30 ++++--- .../cluster/telemetry/telemetry.component.ts | 84 ++++++++++++------- 2 files changed, 70 insertions(+), 44 deletions(-) diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.spec.ts index 72215f6176f9a..baf43e3ffc90d 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.spec.ts @@ -120,16 +120,6 @@ describe('TelemetryComponent', () => { }); }); - it('should update the Telemetry configuration', () => { - component.updateConfig(); - const req = httpTesting.expectOne('api/mgr/module/telemetry'); - expect(req.request.method).toBe('PUT'); - expect(req.request.body).toEqual({ - config: {} - }); - req.flush({}); - }); - it('should disable the Telemetry module', () => { const message = 'Module disabled message.'; const followUpFunc = function () { @@ -303,16 +293,24 @@ describe('TelemetryComponent', () => { }); }); - it('should submit', () => { + it('should submit ', () => { component.onSubmit(); - const req = httpTesting.expectOne('api/telemetry'); - expect(req.request.method).toBe('PUT'); - expect(req.request.body).toEqual({ + const req1 = httpTesting.expectOne('api/telemetry'); + expect(req1.request.method).toBe('PUT'); + expect(req1.request.body).toEqual({ enable: true, license_name: 'sharing-1-0' }); - req.flush({}); - expect(router.navigate).toHaveBeenCalledWith(['']); + req1.flush({}); + const req2 = httpTesting.expectOne({ + url: 'api/mgr/module/telemetry', + method: 'PUT' + }); + expect(req2.request.body).toEqual({ + config: {} + }); + req2.flush({}); + expect(router.url).toBe('/'); }); }); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.ts index 41d9f677553e5..47ebae3be199d 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.ts @@ -25,6 +25,7 @@ export class TelemetryComponent extends CdForm implements OnInit { licenseAgrmt = false; moduleEnabled: boolean; options: Object = {}; + updatedConfig: Object = {}; previewForm: CdFormGroup; requiredFields = [ 'channel_basic', @@ -176,6 +177,23 @@ export class TelemetryComponent extends CdForm implements OnInit { return result; } + private updateChannelsInReport(updatedConfig: Object = {}) { + const channels: string[] = this.report['report']['channels']; + const availableChannels: string[] = this.report['report']['channels_available']; + const updatedChannels = []; + for (const channel of availableChannels) { + const key = `channel_${channel}`; + // channel unchanged or toggled on + if ( + (!updatedConfig.hasOwnProperty(key) && channels.includes(channel)) || + updatedConfig[key] + ) { + updatedChannels.push(channel); + } + } + this.report['report']['channels'] = updatedChannels; + } + private getReport() { this.loadingStart(); @@ -183,6 +201,7 @@ export class TelemetryComponent extends CdForm implements OnInit { (resp: object) => { this.report = resp; this.reportId = resp['report']['report_id']; + this.updateChannelsInReport(this.updatedConfig); this.createPreviewForm(); this.loadingReady(); this.step++; @@ -198,30 +217,19 @@ export class TelemetryComponent extends CdForm implements OnInit { } updateConfig() { - const config = {}; - _.forEach(Object.values(this.options), (option) => { + this.updatedConfig = {}; + for (const option of Object.values(this.options)) { const control = this.configForm.get(option.name); + if (!control.valid) { + this.configForm.setErrors({ cdSubmitButton: true }); + return; + } // Append the option only if the value has been modified. if (control.dirty && control.valid) { - config[option.name] = control.value; - } - }); - this.mgrModuleService.updateConfig('telemetry', config).subscribe( - () => { - this.disableModule( - $localize`Your settings have been applied successfully. \ - Due to privacy/legal reasons the Telemetry module is now disabled until you \ - complete the next step and accept the license.`, - () => { - this.getReport(); - } - ); - }, - () => { - // Reset the 'Submit' button. - this.configForm.setErrors({ cdSubmitButton: true }); + this.updatedConfig[option.name] = control.value; } - ); + } + this.getReport(); } disableModule(message: string = null, followUpFunc: Function = null) { @@ -251,13 +259,33 @@ export class TelemetryComponent extends CdForm implements OnInit { } onSubmit() { - this.telemetryService.enable().subscribe(() => { - this.telemetryNotificationService.setVisibility(false); - this.notificationService.show( - NotificationType.success, - $localize`The Telemetry module has been configured and activated successfully.` - ); - this.router.navigate(['']); - }); + const observables = [ + this.telemetryService.enable(), + this.mgrModuleService.updateConfig('telemetry', this.updatedConfig) + ]; + + observableForkJoin(observables).subscribe( + () => { + this.telemetryNotificationService.setVisibility(false); + this.notificationService.show( + NotificationType.success, + $localize`The Telemetry module has been configured and activated successfully.` + ); + }, + () => { + this.telemetryNotificationService.setVisibility(false); + this.notificationService.show( + NotificationType.error, + $localize`An Error occurred while updating the Telemetry module configuration.\ + Please Try again` + ); + // Reset the 'Update' button. + this.previewForm.setErrors({ cdSubmitButton: true }); + }, + () => { + this.updatedConfig = {}; + this.router.navigate(['']); + } + ); } } From 15211a6378a6fee9316f79ba0b27821891527c38 Mon Sep 17 00:00:00 2001 From: Sarthak0702 Date: Wed, 16 Feb 2022 18:15:35 +0530 Subject: [PATCH 2/2] mgr/dashboard: Contact Info should be visible only when Ident channel is checked Fixes:https://tracker.ceph.com/issues/54133 Signed-off-by: Sarthak0702 --- .../telemetry/telemetry.component.html | 13 ++++ .../telemetry/telemetry.component.spec.ts | 26 ++++--- .../cluster/telemetry/telemetry.component.ts | 68 ++++++++++++------- 3 files changed, 71 insertions(+), 36 deletions(-) diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.html index f84930dc1dcb6..ed3d7b85a765e 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.html @@ -185,6 +185,19 @@ i18n-placeholder> +
+ +
+ +
+
Advanced Settings
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.spec.ts index baf43e3ffc90d..e2d93c4b4526d 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.spec.ts @@ -86,22 +86,28 @@ describe('TelemetryComponent', () => { fixture.debugElement.nativeElement.querySelector('input[id=contact]'); const getDescriptionField = () => fixture.debugElement.nativeElement.querySelector('input[id=description]'); + const checkVisibility = () => { + if (component.showContactInfo) { + expect(getContactField()).toBeTruthy(); + expect(getDescriptionField()).toBeTruthy(); + } else { + expect(getContactField()).toBeFalsy(); + expect(getDescriptionField()).toBeFalsy(); + } + }; - // Initially hidden. - expect(getContactField()).toBeFalsy(); - expect(getDescriptionField()).toBeFalsy(); + // Initial check. + checkVisibility(); - // Show fields. + // toggle fields. component.toggleIdent(); fixture.detectChanges(); - expect(getContactField()).toBeTruthy(); - expect(getDescriptionField()).toBeTruthy(); + checkVisibility(); - // Hide fields. + // toggle fields again. component.toggleIdent(); fixture.detectChanges(); - expect(getContactField()).toBeFalsy(); - expect(getDescriptionField()).toBeFalsy(); + checkVisibility(); }); it('should set module enability to true correctly', () => { @@ -293,7 +299,7 @@ describe('TelemetryComponent', () => { }); }); - it('should submit ', () => { + it('should submit', () => { component.onSubmit(); const req1 = httpTesting.expectOne('api/telemetry'); expect(req1.request.method).toBe('PUT'); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.ts index 47ebae3be199d..882a2fe3c4036 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/telemetry/telemetry.component.ts @@ -25,7 +25,8 @@ export class TelemetryComponent extends CdForm implements OnInit { licenseAgrmt = false; moduleEnabled: boolean; options: Object = {}; - updatedConfig: Object = {}; + newConfig: Object = {}; + configResp: object = {}; previewForm: CdFormGroup; requiredFields = [ 'channel_basic', @@ -36,14 +37,16 @@ export class TelemetryComponent extends CdForm implements OnInit { 'interval', 'proxy', 'contact', - 'description' + 'description', + 'organization' ]; + contactInfofields = ['contact', 'description', 'organization']; report: object = undefined; reportId: number = undefined; sendToUrl = ''; sendToDeviceUrl = ''; step = 1; - showContactInfo = false; + showContactInfo: boolean; constructor( public actionLabels: ActionLabelsI18n, @@ -68,10 +71,11 @@ export class TelemetryComponent extends CdForm implements OnInit { this.moduleEnabled = configResp['enabled']; this.sendToUrl = configResp['url']; this.sendToDeviceUrl = configResp['device_url']; + this.showContactInfo = configResp['channel_ident']; this.options = _.pick(resp[0], this.requiredFields); - const configs = _.pick(configResp, this.requiredFields); + this.configResp = _.pick(configResp, this.requiredFields); this.createConfigForm(); - this.configForm.setValue(configs); + this.configForm.setValue(this.configResp); this.loadingReady(); }, (_error) => { @@ -177,21 +181,21 @@ export class TelemetryComponent extends CdForm implements OnInit { return result; } - private updateChannelsInReport(updatedConfig: Object = {}) { - const channels: string[] = this.report['report']['channels']; + private updateReportFromConfig(updatedConfig: Object = {}) { + // update channels const availableChannels: string[] = this.report['report']['channels_available']; const updatedChannels = []; for (const channel of availableChannels) { const key = `channel_${channel}`; - // channel unchanged or toggled on - if ( - (!updatedConfig.hasOwnProperty(key) && channels.includes(channel)) || - updatedConfig[key] - ) { + if (updatedConfig[key]) { updatedChannels.push(channel); } } this.report['report']['channels'] = updatedChannels; + // update contactInfo + for (const contactInfofield of this.contactInfofields) { + this.report['report'][contactInfofield] = updatedConfig[contactInfofield]; + } } private getReport() { @@ -201,7 +205,7 @@ export class TelemetryComponent extends CdForm implements OnInit { (resp: object) => { this.report = resp; this.reportId = resp['report']['report_id']; - this.updateChannelsInReport(this.updatedConfig); + this.updateReportFromConfig(this.newConfig); this.createPreviewForm(); this.loadingReady(); this.step++; @@ -216,17 +220,22 @@ export class TelemetryComponent extends CdForm implements OnInit { this.showContactInfo = !this.showContactInfo; } - updateConfig() { - this.updatedConfig = {}; + buildReport() { + this.newConfig = {}; for (const option of Object.values(this.options)) { const control = this.configForm.get(option.name); - if (!control.valid) { + // Append the option only if they are valid + if (control.valid) { + this.newConfig[option.name] = control.value; + } else { this.configForm.setErrors({ cdSubmitButton: true }); return; } - // Append the option only if the value has been modified. - if (control.dirty && control.valid) { - this.updatedConfig[option.name] = control.value; + } + // reset contact info field if ident channel is off + if (!this.newConfig['channel_ident']) { + for (const contactInfofield of this.contactInfofields) { + this.newConfig[contactInfofield] = ''; } } this.getReport(); @@ -247,21 +256,28 @@ export class TelemetryComponent extends CdForm implements OnInit { } next() { - if (this.configForm.pristine) { - this.getReport(); - } else { - this.updateConfig(); - } + this.buildReport(); } back() { this.step--; } + getChangedConfig() { + const updatedConfig = {}; + _.forEach(this.requiredFields, (configField) => { + if (!_.isEqual(this.configResp[configField], this.newConfig[configField])) { + updatedConfig[configField] = this.newConfig[configField]; + } + }); + return updatedConfig; + } + onSubmit() { + const updatedConfig = this.getChangedConfig(); const observables = [ this.telemetryService.enable(), - this.mgrModuleService.updateConfig('telemetry', this.updatedConfig) + this.mgrModuleService.updateConfig('telemetry', updatedConfig) ]; observableForkJoin(observables).subscribe( @@ -283,7 +299,7 @@ export class TelemetryComponent extends CdForm implements OnInit { this.previewForm.setErrors({ cdSubmitButton: true }); }, () => { - this.updatedConfig = {}; + this.newConfig = {}; this.router.navigate(['']); } );