hosts = get_hosts(sources)
orch = OrchClient.instance()
if str_to_bool(facts):
- if orch.available():
- hosts_facts = orch.hosts.get_facts()
- return merge_list_of_dicts_by_key(hosts, hosts_facts, 'hostname')
+ if orch.available(['get_facts']):
+ try:
+ hosts_facts = orch.hosts.get_facts()
+ return merge_list_of_dicts_by_key(hosts, hosts_facts, 'hostname')
+
+ except Exception:
+ raise DashboardException(
+ code='invalid_orchestrator_backend', # pragma: no cover
+ msg="Please enable the cephadm orchestrator backend "
+ "(try `ceph orch set backend cephadm`)",
+ component='orchestrator',
+ http_status_code=400)
raise DashboardException(code='orchestrator_status_unavailable', # pragma: no cover
msg="Please configure and enable the orchestrator if you "
}
];
- OrchestratorHelper.mockStatus(true);
+ OrchestratorHelper.mockStatus(false);
hostListSpy.and.callFake(() => of(payload));
fixture.detectChanges();
});
it('should test if host facts are tranformed correctly if orch available', () => {
+ const features = [OrchestratorFeature.HOST_FACTS];
const payload = [
{
hostname: 'host_test',
nic_count: 1
}
];
- OrchestratorHelper.mockStatus(true);
+ OrchestratorHelper.mockStatus(true, features);
hostListSpy.and.callFake(() => of(payload));
fixture.detectChanges();
expect(spans[7].textContent).toBe('Unavailable');
});
+ it('should test if host facts are unavailable if get_fatcs orch feature is not available', () => {
+ const payload = [
+ {
+ hostname: 'host_test',
+ services: [
+ {
+ type: 'osd',
+ id: '0'
+ }
+ ]
+ }
+ ];
+ OrchestratorHelper.mockStatus(true);
+ 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'
+ );
+ expect(spans[7].textContent).toBe('Unavailable');
+ });
+
it('should show force maintenance modal when it is safe to stop host', () => {
const errorMsg = `WARNING: Stopping 1 out of 1 daemons in Grafana service.
Service will not be operational with no daemons left. At
});
}
+ checkHostsFactsAvailable() {
+ const orchFeatures = this.orchStatus.features;
+ if (!_.isEmpty(orchFeatures)) {
+ if (orchFeatures.get_facts.available) {
+ return true;
+ }
+ return false;
+ }
+ return false;
+ }
+
transformHostsData() {
- if (this.orchStatus?.available) {
+ if (this.checkHostsFactsAvailable()) {
_.forEach(this.hosts, (hostKey) => {
hostKey['memory_total_bytes'] = hostKey['memory_total_kb'] * 1024;
hostKey['raw_capacity'] = hostKey['hdd_capacity_bytes'] + hostKey['flash_capacity_bytes'];
.pipe(
mergeMap((orchStatus) => {
this.orchStatus = orchStatus;
-
- return this.hostService.list(`${this.orchStatus?.available}`);
+ const factsAvailable = this.checkHostsFactsAvailable();
+ return this.hostService.list(`${factsAvailable}`);
}),
map((hostList: object[]) =>
hostList.map((host) => {
HOST_LABEL_REMOVE = 'remove_host_label',
HOST_MAINTENANCE_ENTER = 'enter_host_maintenance',
HOST_MAINTENANCE_EXIT = 'exit_host_maintenance',
+ HOST_FACTS = 'get_facts',
SERVICE_LIST = 'describe_service',
SERVICE_CREATE = 'apply',
@contextlib.contextmanager
-def patch_orch(available: bool, hosts: Optional[List[HostSpec]] = None,
+def patch_orch(available: bool, missing_features: Optional[List[str]] = None,
+ hosts: Optional[List[HostSpec]] = None,
inventory: Optional[List[dict]] = None):
with mock.patch('dashboard.controllers.orchestrator.OrchClient.instance') as instance:
fake_client = mock.Mock()
fake_client.available.return_value = available
- fake_client.get_missing_features.return_value = []
+ fake_client.get_missing_features.return_value = missing_features
if hosts is not None:
fake_client.hosts.list.return_value = hosts
'application/vnd.ceph.api.v1.1+json')
self.assertJsonBody(hosts_without_facts)
+ # test with orchestrator available but orch backend!=cephadm
+ with patch_orch(True, missing_features=['get_facts']) as fake_client:
+ mock_get_hosts.return_value = hosts_without_facts
+ # test with ?facts=true
+ self._get('{}?facts=true'.format(self.URL_HOST), version=APIVersion(1, 1))
+ self.assertStatus(400)
+
# test with no orchestrator available
with patch_orch(False):
mock_get_hosts.return_value = hosts_without_facts