From bf6faed0010c22ff599cc2e2e5e7f91f723bfdea Mon Sep 17 00:00:00 2001 From: Nizamudeen A Date: Sat, 8 Mar 2025 13:54:58 +0530 Subject: [PATCH] mgr/dashboard: fix token polling req in multi-cluster UI the req sends the details of every cluster's token in a GET req which is insecure and gets logged in browser and server logs.. fixing that and also stop polling token status every 5s and resort to the 10m interval Fixes: https://tracker.ceph.com/issues/70371 Signed-off-by: Nizamudeen A --- .../dashboard/controllers/multi_cluster.py | 28 ++++---- .../multi-cluster-list.component.ts | 1 - .../app/shared/api/multi-cluster.service.ts | 69 +++---------------- src/pybind/mgr/dashboard/openapi.yaml | 7 +- 4 files changed, 25 insertions(+), 80 deletions(-) diff --git a/src/pybind/mgr/dashboard/controllers/multi_cluster.py b/src/pybind/mgr/dashboard/controllers/multi_cluster.py index 065f571c2e556..9b1cbde0ce8f6 100644 --- a/src/pybind/mgr/dashboard/controllers/multi_cluster.py +++ b/src/pybind/mgr/dashboard/controllers/multi_cluster.py @@ -411,25 +411,29 @@ class MultiCluster(RESTController): return 1 return 0 - def check_token_status_array(self, clusters_token_array): + def check_token_status_array(self): token_status_map = {} + multi_cluster_config = self.load_multi_cluster_config() - for item in clusters_token_array: - cluster_name = item['name'] - token = item['token'] - user = item['user'] - status = self.check_token_status_expiration(token) - time_left = self.get_time_left(token) - token_status_map[cluster_name] = {'status': status, 'user': user, - 'time_left': time_left} + if 'config' in multi_cluster_config: + for _, config in multi_cluster_config['config'].items(): + cluster_name = config[0]['name'] + token = config[0]['token'] + user = config[0]['user'] + status = self.check_token_status_expiration(token) + time_left = self.get_time_left(token) + token_status_map[cluster_name] = { + 'status': status, + 'user': user, + 'time_left': time_left + } return token_status_map @Endpoint() @ReadPermission - def check_token_status(self, clustersTokenMap=None): - clusters_token_map = json.loads(clustersTokenMap) - return self.check_token_status_array(clusters_token_map) + def check_token_status(self): + return self.check_token_status_array() @Endpoint() @ReadPermission diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.ts index ab03649e6377f..a9ca408f4874f 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.ts @@ -277,6 +277,5 @@ export class MultiClusterListComponent extends ListWithDetails implements OnInit refresh() { this.multiClusterService.refresh(); - this.multiClusterService.refreshTokenStatus(); } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/multi-cluster.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/multi-cluster.service.ts index e3968ae38e8f0..0aa57437f2521 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/multi-cluster.service.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/multi-cluster.service.ts @@ -1,4 +1,4 @@ -import { HttpClient, HttpParams } from '@angular/common/http'; +import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { TimerService } from '../services/timer.service'; @@ -32,56 +32,14 @@ export class MultiClusterService { .subscribe(this.getClusterObserver()); } - getTempMap(clustersConfig: any) { - const tempMap = new Map(); - Object.keys(clustersConfig).forEach((clusterKey: string) => { - const clusterDetailsList = clustersConfig[clusterKey]; - clusterDetailsList.forEach((clusterDetails: any) => { - if (clusterDetails['token'] && clusterDetails['name'] && clusterDetails['user']) { - tempMap.set(clusterDetails['name'], { - token: clusterDetails['token'], - user: clusterDetails['user'] - }); - } - }); - }); - return tempMap; - } - startClusterTokenStatusPolling() { - let clustersTokenMap = new Map(); - const dataSubscription = this.subscribeOnce((resp: any) => { - const clustersConfig = resp['config']; - let tempMap = new Map(); - if (clustersConfig) { - tempMap = this.getTempMap(clustersConfig); - Object.keys(clustersConfig).forEach((clusterKey: string) => { - const clusterDetailsList = clustersConfig[clusterKey]; - clusterDetailsList.forEach((clusterDetails: any) => { - if (clusterDetails['token'] && clusterDetails['name'] && clusterDetails['user']) { - tempMap.set(clusterDetails['name'], { - token: clusterDetails['token'], - user: clusterDetails['user'] - }); - } - }); - }); - - if (tempMap.size > 0) { - clustersTokenMap = tempMap; - if (dataSubscription) { - dataSubscription.unsubscribe(); - } - this.checkAndStartTimer(clustersTokenMap); - } - } - }); + this.checkAndStartTimer(); } - private checkAndStartTimer(clustersTokenMap: Map) { - this.checkTokenStatus(clustersTokenMap).subscribe(this.getClusterTokenStatusObserver()); + private checkAndStartTimer() { + this.checkTokenStatus().subscribe(this.getClusterTokenStatusObserver()); this.timerService - .get(() => this.checkTokenStatus(clustersTokenMap), this.TOKEN_CHECK_INTERVAL) + .get(() => this.checkTokenStatus(), this.TOKEN_CHECK_INTERVAL) .subscribe(this.getClusterTokenStatusObserver()); } @@ -94,11 +52,7 @@ export class MultiClusterService { } refreshTokenStatus() { - this.subscribeOnce((resp: any) => { - const clustersConfig = resp['config']; - let tempMap = this.getTempMap(clustersConfig); - return this.checkTokenStatus(tempMap).subscribe(this.getClusterTokenStatusObserver()); - }); + return this.checkTokenStatus().subscribe(this.getClusterTokenStatusObserver()); } subscribeOnce(next: (data: any) => void, error?: (error: any) => void) { @@ -203,15 +157,8 @@ export class MultiClusterService { }; } - checkTokenStatus( - clustersTokenMap: Map - ): Observable { - let data = [...clustersTokenMap].map(([key, { token, user }]) => ({ name: key, token, user })); - - let params = new HttpParams(); - params = params.set('clustersTokenMap', JSON.stringify(data)); - - return this.http.get('api/multi-cluster/check_token_status', { params }); + checkTokenStatus(): Observable { + return this.http.get('api/multi-cluster/check_token_status'); } showPrometheusDelayMessage(showDeletionMessage?: boolean) { diff --git a/src/pybind/mgr/dashboard/openapi.yaml b/src/pybind/mgr/dashboard/openapi.yaml index f35e75ac01e27..d107f66443706 100755 --- a/src/pybind/mgr/dashboard/openapi.yaml +++ b/src/pybind/mgr/dashboard/openapi.yaml @@ -7278,12 +7278,7 @@ paths: - Multi-cluster /api/multi-cluster/check_token_status: get: - parameters: - - allowEmptyValue: true - in: query - name: clustersTokenMap - schema: - type: string + parameters: [] responses: '200': content: -- 2.39.5