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:
@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')
[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"
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;
beforeEach(() => {
fixture = TestBed.createComponent(ActiveAlertListComponent);
component = fixture.componentInstance;
+ let prometheusAlertService = TestBed.inject(PrometheusAlertService);
+ spyOn(prometheusAlertService, 'getAlerts').and.callFake(() => of([]));
});
it('should create', () => {
cellTemplate: this.externalLinkTpl
}
];
+ this.prometheusAlertService.getAlerts(true);
}
updateSelection(selection: CdTableSelection) {
schemas: [NO_ERRORS_SCHEMA],
providers: [
{ provide: SummaryService, useClass: SummaryServiceMock },
- {
- provide: PrometheusAlertService,
- useValue: {
- activeCriticalAlerts: 2,
- activeWarningAlerts: 1
- }
- },
+ PrometheusAlertService,
CssHelper,
PgCategoryService
]
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', () => {
this.getDetailsCardData();
this.getTelemetryReport();
this.managedByConfig$ = this.settingsService.getValues('MANAGED_BY_CLUSTERS');
+ this.prometheusAlertService.getAlerts(true);
}
getTelemetryText(): string {
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');
});
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 });
}
}
private triggerPrometheusAlerts() {
- this.prometheusAlertService.refresh();
+ this.prometheusAlertService.refresh(true);
this.prometheusNotificationService.refresh();
}
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)) {
});
}
- refresh() {
- this.getAlerts();
+ refresh(clusterFilteredAlerts?: boolean) {
+ this.getAlerts(clusterFilteredAlerts);
this.getRules();
}
- Pool
/api/prometheus:
get:
- parameters: []
+ parameters:
+ - default: false
+ in: query
+ name: cluster_filter
+ schema:
+ type: boolean
responses:
'200':
content: