]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: filter alerts with cluster fsid and donot allow clusters 56579/head
authorAashish Sharma <aasharma@li-e74156cc-2f67-11b2-a85c-e98659a63c5c.ibm.com>
Fri, 29 Mar 2024 09:37:12 +0000 (15:07 +0530)
committerAashish Sharma <aasharma@li-e74156cc-2f67-11b2-a85c-e98659a63c5c.ibm.com>
Wed, 24 Apr 2024 07:34:59 +0000 (13:04 +0530)
with version less than hub cluster to be added in multi-cluster

Signed-off-by: Aashish Sharma <aasharma@redhat.com>
12 files changed:
src/pybind/mgr/dashboard/controllers/multi_cluster.py
src/pybind/mgr/dashboard/controllers/prometheus.py
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/active-alert-list/active-alert-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard-v3/dashboard/dashboard-v3.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard-v3/dashboard/dashboard-v3.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/api/prometheus.service.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/api/prometheus.service.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/components/notifications-sidebar/notifications-sidebar.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/services/prometheus-alert.service.ts
src/pybind/mgr/dashboard/openapi.yaml

index 75095dcbd467cacf072c110c62e6c0b8342073fb..cc6a7e203d3bfd9db3f8ee508e886aeff917a1a8 100644 (file)
@@ -128,6 +128,16 @@ class MultiCluster(RESTController):
 
     def check_cluster_connection(self, url, payload, username, ssl_verify, ssl_certificate):
         try:
+            hub_cluster_version = mgr.version.split('ceph version ')[1]
+            multi_cluster_content = self._proxy('GET', url, 'api/multi-cluster/get_config',
+                                                verify=ssl_verify, cert=ssl_certificate)
+            if 'status' in multi_cluster_content and multi_cluster_content['status'] == '404 Not Found':   # noqa E501 #pylint: disable=line-too-long
+                raise DashboardException(msg=f'The ceph cluster you are attempting to connect \
+                                         to does not support the multi-cluster feature. \
+                                         Please ensure that the cluster you are connecting \
+                                         to is upgraded to { hub_cluster_version } to enable the \
+                                         multi-cluster functionality.',
+                                         code='invalid_version', component='multi-cluster')
             content = self._proxy('POST', url, 'api/auth', payload=payload,
                                   verify=ssl_verify, cert=ssl_certificate)
             if 'token' not in content:
index ffc6407b4a9f1963cfbbe978668f28d1d9a5eb04..75a607d1e31119a289374b73937308dc2ba8a92b 100644 (file)
@@ -126,7 +126,13 @@ class PrometheusRESTController(RESTController):
 @APIRouter('/prometheus', Scope.PROMETHEUS)
 @APIDoc("Prometheus Management API", "Prometheus")
 class Prometheus(PrometheusRESTController):
-    def list(self, **params):
+    def list(self, cluster_filter=False, **params):
+        if cluster_filter:
+            try:
+                fsid = mgr.get('config')['fsid']
+            except KeyError:
+                raise DashboardException("Cluster fsid not found", component='prometheus')
+            return self.alert_proxy('GET', f'/alerts?filter=cluster={fsid}', params)
         return self.alert_proxy('GET', '/alerts', params)
 
     @RESTController.Collection(method='GET')
index 3e9e27c33bacd24df1af84eb9494ae71286d075d..0b209abaa505d3551a83533fc94cfa8850e7885d 100644 (file)
@@ -86,7 +86,7 @@
                      [fullHeight]="true"
                      *ngIf="queriesResults.CLUSTER_COUNT && queriesResults.CLUSTER_COUNT[0]">
               <span class="text-center">
-                <h3 *ngIf="queriesResults['HEALTH_ERROR_COUNT'][0][1] === '0' && queriesResults['HEALTH_WARNING_COUNT'][0][1] === '0'">{{ queriesResults.CLUSTER_COUNT[0][1] }}</h3>
+                <h3 *ngIf="queriesResults['HEALTH_ERROR_COUNT'][0][1] === '0' && queriesResults['HEALTH_OK_COUNT'][0][1] === '0' && queriesResults['HEALTH_WARNING_COUNT'][0][1] === '0'">{{ queriesResults.CLUSTER_COUNT[0][1] }}</h3>
                 <h3 class="text-danger"
                     *ngIf="queriesResults.HEALTH_ERROR_COUNT[0][1] !== '0'">
                   <i [ngClass]="icons.danger"></i>
                   <i [ngClass]="icons.warning"></i>
                     {{ queriesResults.HEALTH_WARNING_COUNT[0][1] }}
                 </h3>
+                <h3 class="text-danger"
+                    *ngIf="queriesResults.HEALTH_ERROR_COUNT[0][1] !== '0'">
+                  <i [ngClass]="icons.danger"></i>
+                  {{ queriesResults.HEALTH_ERROR_COUNT[0][1] }}
+                </h3>
+                <h3 class="text-success"
+                    *ngIf="queriesResults.HEALTH_OK_COUNT[0][1] !== '0'">
+                  <i [ngClass]="icons.success"></i>
+                    {{ queriesResults.HEALTH_OK_COUNT[0][1] }}
+                </h3>
               </span>
             </cd-card>
             <cd-card cardTitle="Alerts"
index 7b10c20aa0911b2fe434956c810ccec91321976a..5bfd2898866af76796f6ee52369952ddc01b612d 100644 (file)
@@ -14,6 +14,8 @@ import { TableActionsComponent } from '~/app/shared/datatable/table-actions/tabl
 import { SharedModule } from '~/app/shared/shared.module';
 import { configureTestBed, PermissionHelper } from '~/testing/unit-test-helper';
 import { ActiveAlertListComponent } from './active-alert-list.component';
+import { PrometheusAlertService } from '~/app/shared/services/prometheus-alert.service';
+import { of } from 'rxjs';
 
 describe('ActiveAlertListComponent', () => {
   let component: ActiveAlertListComponent;
@@ -37,6 +39,8 @@ describe('ActiveAlertListComponent', () => {
   beforeEach(() => {
     fixture = TestBed.createComponent(ActiveAlertListComponent);
     component = fixture.componentInstance;
+    let prometheusAlertService = TestBed.inject(PrometheusAlertService);
+    spyOn(prometheusAlertService, 'getAlerts').and.callFake(() => of([]));
   });
 
   it('should create', () => {
index de027bfec50756412d0abd949cf9b1e81b4aad58..e3892f0a67942b28eae4cc6307a94cac6e797a3e 100644 (file)
@@ -105,6 +105,7 @@ export class ActiveAlertListComponent extends PrometheusListHelper implements On
         cellTemplate: this.externalLinkTpl
       }
     ];
+    this.prometheusAlertService.getAlerts(true);
   }
 
   updateSelection(selection: CdTableSelection) {
index 60a30456ef711d6f3f301e31014c3b4b7e2ab5db..b87888f4f4a0ef2793020d512668478196f158e3 100644 (file)
@@ -141,13 +141,7 @@ describe('Dashbord Component', () => {
     schemas: [NO_ERRORS_SCHEMA],
     providers: [
       { provide: SummaryService, useClass: SummaryServiceMock },
-      {
-        provide: PrometheusAlertService,
-        useValue: {
-          activeCriticalAlerts: 2,
-          activeWarningAlerts: 1
-        }
-      },
+      PrometheusAlertService,
       CssHelper,
       PgCategoryService
     ]
@@ -169,11 +163,14 @@ describe('Dashbord Component', () => {
     orchestratorService = TestBed.inject(OrchestratorService);
     getHealthSpy = spyOn(TestBed.inject(HealthService), 'getMinimalHealth');
     getHealthSpy.and.returnValue(of(healthPayload));
-    spyOn(TestBed.inject(PrometheusService), 'ifAlertmanagerConfigured').and.callFake((fn) => fn());
     getAlertsSpy = spyOn(TestBed.inject(PrometheusService), 'getAlerts');
     getAlertsSpy.and.returnValue(of(alertsPayload));
     component.prometheusAlertService.alerts = alertsPayload;
     component.isAlertmanagerConfigured = true;
+    let prometheusAlertService = TestBed.inject(PrometheusAlertService);
+    spyOn(prometheusAlertService, 'getAlerts').and.callFake(() => of([]));
+    prometheusAlertService.activeCriticalAlerts = 2;
+    prometheusAlertService.activeWarningAlerts = 1;
   });
 
   it('should create', () => {
index d8528f6cff851f13e178c720d8cfaf9d3a97614b..9b3c050064f95b90786ca2001e993e54d847a7c6 100644 (file)
@@ -120,6 +120,7 @@ export class DashboardV3Component extends PrometheusListHelper implements OnInit
     this.getDetailsCardData();
     this.getTelemetryReport();
     this.managedByConfig$ = this.settingsService.getValues('MANAGED_BY_CLUSTERS');
+    this.prometheusAlertService.getAlerts(true);
   }
 
   getTelemetryText(): string {
index 65fc174b92e347079c7f422f68fc73ddee4db237..9694084559518ab56bfbe6115c5067ef90a6d103 100644 (file)
@@ -30,7 +30,7 @@ describe('PrometheusService', () => {
 
   it('should get alerts', () => {
     service.getAlerts().subscribe();
-    const req = httpTesting.expectOne('api/prometheus');
+    const req = httpTesting.expectOne('api/prometheus?cluster_filter=false');
     expect(req.request.method).toBe('GET');
   });
 
index 2b469e837d22ae39e45a3330c193effe2bc7a60b..1a241361f7f25fd7f07c8efa60e51e194ddf54f7 100644 (file)
@@ -58,7 +58,8 @@ export class PrometheusService {
     this.disableSetting(this.settingsKey.prometheus);
   }
 
-  getAlerts(params = {}): Observable<AlertmanagerAlert[]> {
+  getAlerts(clusterFilteredAlerts = false, params = {}): Observable<AlertmanagerAlert[]> {
+    params['cluster_filter'] = clusterFilteredAlerts;
     return this.http.get<AlertmanagerAlert[]>(this.baseURL, { params });
   }
 
index 3868f55ba53e1ab472789d8ebd3ad0cb21617c73..a662a898b163bca68dc41aca67b607e64e67e249 100644 (file)
@@ -154,7 +154,7 @@ export class NotificationsSidebarComponent implements OnInit, OnDestroy {
   }
 
   private triggerPrometheusAlerts() {
-    this.prometheusAlertService.refresh();
+    this.prometheusAlertService.refresh(true);
     this.prometheusNotificationService.refresh();
   }
 
index 2830fd00c2422735d98cd0436c430b6a885ffbfe..6c9ab25cbc23b7437418464fe06232f3193e6d9f 100644 (file)
@@ -26,9 +26,9 @@ export class PrometheusAlertService {
     private prometheusService: PrometheusService
   ) {}
 
-  getAlerts() {
+  getAlerts(clusterFilteredAlerts?: boolean) {
     this.prometheusService.ifAlertmanagerConfigured(() => {
-      this.prometheusService.getAlerts().subscribe(
+      this.prometheusService.getAlerts(clusterFilteredAlerts).subscribe(
         (alerts) => this.handleAlerts(alerts),
         (resp) => {
           if ([404, 504].includes(resp.status)) {
@@ -54,8 +54,8 @@ export class PrometheusAlertService {
     });
   }
 
-  refresh() {
-    this.getAlerts();
+  refresh(clusterFilteredAlerts?: boolean) {
+    this.getAlerts(clusterFilteredAlerts);
     this.getRules();
   }
 
index d43f48fcbf701c926d349d1e149c9e7b6f4c358d..1c004bd8b3c7006a72a41bab03b4ef1c22de4002 100644 (file)
@@ -10300,7 +10300,12 @@ paths:
       - Pool
   /api/prometheus:
     get:
-      parameters: []
+      parameters:
+      - default: false
+        in: query
+        name: cluster_filter
+        schema:
+          type: boolean
       responses:
         '200':
           content: