diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/hosts.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/hosts.e2e-spec.ts
index c1935a78383..e4f9936c3e3 100644
--- a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/hosts.e2e-spec.ts
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/hosts.e2e-spec.ts
@@ -31,9 +31,5 @@ describe('Hosts page', () => {
it('should check at least one host is present', () => {
hosts.check_for_host();
});
-
- it('should check services link(s) work for first host', () => {
- hosts.check_services_links();
- });
});
});
diff --git a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/hosts.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/hosts.po.ts
index ffac83ba67b..0682b01c6de 100644
--- a/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/hosts.po.ts
+++ b/src/pybind/mgr/dashboard/frontend/cypress/integration/cluster/hosts.po.ts
@@ -19,28 +19,6 @@ export class HostsPageHelper extends PageHelper {
this.getTableCount('total').should('not.be.eq', 0);
}
- // function that checks all services links work for first
- // host in table
- check_services_links() {
- // check that text (links) is present in services box
- let links_tested = 0;
-
- cy.get('cd-hosts a.service-link')
- .should('have.length.greaterThan', 0)
- .then(($elems) => {
- $elems.each((_i, $el) => {
- // click link, check it worked by looking for changed breadcrumb,
- // navigate back to hosts page, repeat until all links checked
- cy.contains('a', $el.innerText).should('exist').click();
- this.expectBreadcrumbText('Performance Counters');
- this.navigateTo();
- links_tested++;
- });
- // check if any links were actually tested
- expect(links_tested).gt(0);
- });
- }
-
add(hostname: string, exist?: boolean, maintenance?: boolean, labels: string[] = []) {
cy.get(`${this.pages.add.id}`).within(() => {
cy.get('#hostname').type(hostname);
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.html
index 5f2da414964..b41ecfa8663 100644
--- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.html
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.html
@@ -47,15 +47,9 @@
-
- {{ service.type }}.{{ service.id }}
-
- {{ service.type }}.{{ service.id }}
-
- ,
+
+ {{ instance }}
+
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.spec.ts
index f91a8ff8376..0d691f62acf 100644
--- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.spec.ts
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.spec.ts
@@ -117,6 +117,56 @@ describe('HostsComponent', () => {
expect(spans[0].textContent).toBe(hostname);
});
+ it('should show the exact count of the repeating daemons', () => {
+ const hostname = 'ceph.dev';
+ const payload = [
+ {
+ services: [
+ {
+ type: 'mgr',
+ id: 'x'
+ },
+ {
+ type: 'mgr',
+ id: 'y'
+ },
+ {
+ type: 'osd',
+ id: '0'
+ },
+ {
+ type: 'osd',
+ id: '1'
+ },
+ {
+ type: 'osd',
+ id: '2'
+ },
+ {
+ type: 'rgw',
+ id: 'rgw'
+ }
+ ],
+ hostname: hostname,
+ labels: ['foo', 'bar']
+ }
+ ];
+
+ OrchestratorHelper.mockStatus(false);
+ hostListSpy.and.callFake(() => of(payload));
+ fixture.detectChanges();
+
+ component.getHosts(new CdTableFetchDataContext(() => undefined));
+ fixture.detectChanges();
+
+ const spans = fixture.debugElement.nativeElement.querySelectorAll(
+ '.datatable-body-cell-label span span.badge.badge-background-primary'
+ );
+ expect(spans[0].textContent).toContain('mgr: 2');
+ expect(spans[1].textContent).toContain('osd: 3');
+ expect(spans[2].textContent).toContain('rgw: 1');
+ });
+
it('should test if host facts are tranformed correctly if orch available', () => {
const features = [OrchestratorFeature.HOST_FACTS];
const payload = [
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.ts
index f7df997c37b..60cedf853c9 100644
--- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.ts
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.ts
@@ -197,9 +197,9 @@ export class HostsComponent extends ListWithDetails implements OnDestroy, OnInit
flexGrow: 1
},
{
- name: $localize`Services`,
- prop: 'services',
- flexGrow: 2,
+ name: $localize`Service Instances`,
+ prop: 'service_instances',
+ flexGrow: 1,
cellTemplate: this.servicesTpl
},
{
@@ -483,15 +483,6 @@ export class HostsComponent extends ListWithDetails implements OnDestroy, OnInit
if (this.isLoadingHosts) {
return;
}
- const typeToPermissionKey = {
- mds: 'cephfs',
- mon: 'monitor',
- osd: 'osd',
- rgw: 'rgw',
- 'rbd-mirror': 'rbdMirroring',
- mgr: 'manager',
- 'tcmu-runner': 'iscsi'
- };
this.isLoadingHosts = true;
this.sub = this.orchService
.status()
@@ -503,11 +494,13 @@ export class HostsComponent extends ListWithDetails implements OnDestroy, OnInit
}),
map((hostList: object[]) =>
hostList.map((host) => {
+ const counts = {};
+ host['service_instances'] = new Set();
+ host['services'].forEach((service: any) => {
+ counts[service.type] = (counts[service.type] || 0) + 1;
+ });
host['services'].map((service: any) => {
- service.cdLink = `/perf_counters/${service.type}/${encodeURIComponent(service.id)}`;
- const permission = this.permissions[typeToPermissionKey[service.type]];
- service.canRead = permission ? permission.read : false;
- return service;
+ host['service_instances'].add(`${service.type}: ${counts[service.type]}`);
});
return host;
})