From: Abhishek Desai Date: Fri, 16 Jan 2026 14:31:54 +0000 (+0530) Subject: mgr/dashboard : Add Cert Status column to services page X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=0ef647c8fafc0ed4706f0e0317f1849476c62370;p=ceph.git mgr/dashboard : Add Cert Status column to services page fixes : https://tracker.ceph.com/issues/74411 Signed-off-by: Abhishek Desai --- diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.html index 042b180d1ba6..07380d6a169c 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.html @@ -62,3 +62,12 @@ {{row.service_name}} + + + @if (row.certificate) { + {{ formatCertificateStatus(row.certificate) }} + } @else { + - + } + diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.ts index 7a5e8ee54b75..782650c8eafc 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/services.component.ts @@ -1,3 +1,4 @@ +import { DatePipe } from '@angular/common'; import { Component, Input, OnChanges, OnInit, TemplateRef, ViewChild } from '@angular/core'; import { Router } from '@angular/router'; @@ -18,7 +19,11 @@ import { FinishedTask } from '~/app/shared/models/finished-task'; import { OrchestratorFeature } from '~/app/shared/models/orchestrator.enum'; import { OrchestratorStatus } from '~/app/shared/models/orchestrator.interface'; import { Permissions } from '~/app/shared/models/permissions'; -import { CephServiceSpec } from '~/app/shared/models/service.interface'; +import { + CephCertificateStatus, + CephServiceCertificate, + CephServiceSpec +} from '~/app/shared/models/service.interface'; import { RelativeDatePipe } from '~/app/shared/pipes/relative-date.pipe'; import { AuthStorageService } from '~/app/shared/services/auth-storage.service'; import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service'; @@ -35,7 +40,7 @@ const BASE_URL = 'services'; selector: 'cd-services', templateUrl: './services.component.html', styleUrls: ['./services.component.scss'], - providers: [{ provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) }], + providers: [DatePipe, { provide: URLBuilderService, useValue: new URLBuilderService(BASE_URL) }], standalone: false }) export class ServicesComponent extends ListWithDetails implements OnChanges, OnInit { @@ -45,6 +50,8 @@ export class ServicesComponent extends ListWithDetails implements OnChanges, OnI public runningTpl: TemplateRef; @ViewChild('urlTpl', { static: true }) public urlTpl: TemplateRef; + @ViewChild('certificateStatusTpl', { static: true }) + public certificateStatusTpl: TemplateRef; @Input() hostname: string; @@ -86,7 +93,8 @@ export class ServicesComponent extends ListWithDetails implements OnChanges, OnI private taskWrapperService: TaskWrapperService, private router: Router, private settingsService: SettingsService, - private cdsModalService: ModalCdsService + private cdsModalService: ModalCdsService, + private datePipe: DatePipe ) { super(); this.permissions = this.authStorageService.getPermissions(); @@ -185,6 +193,12 @@ export class ServicesComponent extends ListWithDetails implements OnChanges, OnI undefined: '-', '': '-' } + }, + { + name: $localize`Certificate Status`, + prop: 'certificate.status', + flexGrow: 2, + cellTemplate: this.certificateStatusTpl } ]; @@ -300,4 +314,30 @@ export class ServicesComponent extends ListWithDetails implements OnChanges, OnI this.serviceUrls[serviceType] = url; }); } + + formatCertificateStatus(cert: CephServiceCertificate): string { + if (!cert || !cert.requires_certificate || !cert.status) { + return '-'; + } + + const formattedDate = cert.expiry_date + ? this.datePipe.transform(cert.expiry_date, 'dd MMM y') + : null; + + switch (cert.status) { + case CephCertificateStatus.valid: + return formattedDate ? $localize`Valid - ${formattedDate}` : $localize`Valid`; + case CephCertificateStatus.expiring: + case CephCertificateStatus.expiringSoon: + return formattedDate + ? $localize`Expiring soon - ${formattedDate}` + : $localize`Expiring soon`; + case CephCertificateStatus.expired: + return formattedDate ? $localize`Expired - ${formattedDate}` : $localize`Expired`; + case CephCertificateStatus.notConfigured: + return '-'; + default: + return formattedDate ? `${cert.status} - ${formattedDate}` : cert.status; + } + } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/service.interface.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/service.interface.ts index c79a9cb4e74a..6ee238e76fea 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/models/service.interface.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/models/service.interface.ts @@ -7,6 +7,27 @@ export interface CephServiceStatus { created: Date; } +export enum CephCertificateStatus { + valid = 'valid', + expired = 'expired', + expiring = 'expiring', + expiringSoon = 'expiring_soon', + notConfigured = 'not_configured', + invalid = 'invalid' +} + +export interface CephServiceCertificate { + cert_name: string; + scope: string; + requires_certificate: boolean; + status: CephCertificateStatus | string; + days_to_expiration: number; + signed_by: string; + has_certificate: boolean; + certificate_source: string; + expiry_date: string; +} + // This will become handy when creating arbitrary services export interface CephServiceSpec { service_name: string; @@ -14,6 +35,7 @@ export interface CephServiceSpec { service_id: string; unmanaged: boolean; status: CephServiceStatus; + certificate?: CephServiceCertificate; spec: CephServiceAdditionalSpec; placement: CephServicePlacement; }