@openshift-assisted/ui-lib 2.9.13-cim → 2.9.15-cim

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/build/@types/cim/components/Agent/AgentStatus.d.ts.map +1 -1
  2. package/build/@types/cim/components/Agent/AgentTable.d.ts.map +1 -1
  3. package/build/@types/cim/components/Agent/AgentsSelectionTable.d.ts.map +1 -1
  4. package/build/@types/cim/components/Agent/BMCForm.d.ts.map +1 -1
  5. package/build/@types/cim/components/Agent/tableUtils.d.ts +10 -5
  6. package/build/@types/cim/components/Agent/tableUtils.d.ts.map +1 -1
  7. package/build/@types/cim/components/ClusterDeployment/ClusterDeploymentDetailsTable.d.ts.map +1 -1
  8. package/build/@types/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.d.ts.map +1 -1
  9. package/build/@types/cim/components/ClusterDeployment/ClusterDeploymentHostsNetworkTable.d.ts.map +1 -1
  10. package/build/@types/cim/components/Hypershift/HostedClusterWizard/HostsStep/HostsForm.d.ts.map +1 -1
  11. package/build/@types/cim/components/Hypershift/HostedClusterWizard/HostsStep/HostsStep.d.ts.map +1 -1
  12. package/build/@types/cim/components/Hypershift/HostedClusterWizard/HostsStep/types.d.ts +2 -0
  13. package/build/@types/cim/components/Hypershift/HostedClusterWizard/HostsStep/types.d.ts.map +1 -1
  14. package/build/@types/cim/components/Hypershift/utils/status.d.ts.map +1 -1
  15. package/build/@types/cim/components/InfraEnv/InfraEnvAgentTable.d.ts.map +1 -1
  16. package/build/@types/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.d.ts.map +1 -1
  17. package/build/@types/cim/components/InfraEnv/InfraTableToolbar.d.ts.map +1 -1
  18. package/build/@types/cim/components/helpers/agentStatus.d.ts +3 -2
  19. package/build/@types/cim/components/helpers/agentStatus.d.ts.map +1 -1
  20. package/build/@types/cim/components/helpers/agents.d.ts.map +1 -1
  21. package/build/@types/cim/components/helpers/status.d.ts +5 -2
  22. package/build/@types/cim/components/helpers/status.d.ts.map +1 -1
  23. package/build/@types/cim/components/modals/MassApproveAgentModal.d.ts.map +1 -1
  24. package/build/@types/cim/components/modals/MassDeleteAgentModal.d.ts.map +1 -1
  25. package/build/@types/common/components/hosts/HostRowDetail.d.ts.map +1 -1
  26. package/build/@types/common/components/hosts/HostStatus.d.ts.map +1 -1
  27. package/build/@types/common/components/hosts/status.d.ts +2 -1
  28. package/build/@types/common/components/hosts/status.d.ts.map +1 -1
  29. package/build/@types/common/components/hosts/tableUtils.d.ts +1 -1
  30. package/build/@types/common/components/hosts/tableUtils.d.ts.map +1 -1
  31. package/build/@types/common/components/storage/StorageDetail.d.ts.map +1 -1
  32. package/build/@types/ocm/components/clusterDetail/HostInventoryExpandable.d.ts.map +1 -1
  33. package/build/@types/ocm/components/hosts/HardwareStatus.d.ts.map +1 -1
  34. package/build/@types/ocm/components/hosts/NetworkingStatus.d.ts.map +1 -1
  35. package/build/cjs/cim/components/Agent/AgentStatus.js +4 -3
  36. package/build/cjs/cim/components/Agent/AgentStatus.js.map +1 -1
  37. package/build/cjs/cim/components/Agent/AgentTable.js +4 -1
  38. package/build/cjs/cim/components/Agent/AgentTable.js.map +1 -1
  39. package/build/cjs/cim/components/Agent/AgentsSelectionTable.js +4 -0
  40. package/build/cjs/cim/components/Agent/AgentsSelectionTable.js.map +1 -1
  41. package/build/cjs/cim/components/Agent/BMCForm.js +21 -3
  42. package/build/cjs/cim/components/Agent/BMCForm.js.map +1 -1
  43. package/build/cjs/cim/components/Agent/tableUtils.js +36 -34
  44. package/build/cjs/cim/components/Agent/tableUtils.js.map +1 -1
  45. package/build/cjs/cim/components/ClusterDeployment/ClusterDeploymentDetailsTable.js +4 -1
  46. package/build/cjs/cim/components/ClusterDeployment/ClusterDeploymentDetailsTable.js.map +1 -1
  47. package/build/cjs/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.js +19 -2
  48. package/build/cjs/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.js.map +1 -1
  49. package/build/cjs/cim/components/ClusterDeployment/ClusterDeploymentHostsNetworkTable.js +18 -3
  50. package/build/cjs/cim/components/ClusterDeployment/ClusterDeploymentHostsNetworkTable.js.map +1 -1
  51. package/build/cjs/cim/components/Hypershift/HostedClusterWizard/HostsStep/HostsForm.js +10 -0
  52. package/build/cjs/cim/components/Hypershift/HostedClusterWizard/HostsStep/HostsForm.js.map +1 -1
  53. package/build/cjs/cim/components/Hypershift/HostedClusterWizard/HostsStep/HostsStep.js +2 -1
  54. package/build/cjs/cim/components/Hypershift/HostedClusterWizard/HostsStep/HostsStep.js.map +1 -1
  55. package/build/cjs/cim/components/Hypershift/utils/status.js +3 -1
  56. package/build/cjs/cim/components/Hypershift/utils/status.js.map +1 -1
  57. package/build/cjs/cim/components/InfraEnv/InfraEnvAgentTable.js +20 -7
  58. package/build/cjs/cim/components/InfraEnv/InfraEnvAgentTable.js.map +1 -1
  59. package/build/cjs/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.js +5 -2
  60. package/build/cjs/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.js.map +1 -1
  61. package/build/cjs/cim/components/InfraEnv/InfraTableToolbar.js +17 -10
  62. package/build/cjs/cim/components/InfraEnv/InfraTableToolbar.js.map +1 -1
  63. package/build/cjs/cim/components/helpers/agentStatus.js +17 -15
  64. package/build/cjs/cim/components/helpers/agentStatus.js.map +1 -1
  65. package/build/cjs/cim/components/helpers/agents.js +2 -2
  66. package/build/cjs/cim/components/helpers/agents.js.map +1 -1
  67. package/build/cjs/cim/components/helpers/status.js +40 -22
  68. package/build/cjs/cim/components/helpers/status.js.map +1 -1
  69. package/build/cjs/cim/components/helpers/toAssisted.js +2 -2
  70. package/build/cjs/cim/components/helpers/toAssisted.js.map +1 -1
  71. package/build/cjs/cim/components/modals/MassApproveAgentModal.js +8 -5
  72. package/build/cjs/cim/components/modals/MassApproveAgentModal.js.map +1 -1
  73. package/build/cjs/cim/components/modals/MassDeleteAgentModal.js +40 -33
  74. package/build/cjs/cim/components/modals/MassDeleteAgentModal.js.map +1 -1
  75. package/build/cjs/common/components/clusterWizard/networkingSteps/ManagedNetworkingControlGroup.js +1 -1
  76. package/build/cjs/common/components/clusterWizard/networkingSteps/ManagedNetworkingControlGroup.js.map +1 -1
  77. package/build/cjs/common/components/hosts/HostRowDetail.js +14 -14
  78. package/build/cjs/common/components/hosts/HostRowDetail.js.map +1 -1
  79. package/build/cjs/common/components/hosts/HostStatus.js +2 -1
  80. package/build/cjs/common/components/hosts/HostStatus.js.map +1 -1
  81. package/build/cjs/common/components/hosts/status.js +54 -53
  82. package/build/cjs/common/components/hosts/status.js.map +1 -1
  83. package/build/cjs/common/components/hosts/tableUtils.js +3 -3
  84. package/build/cjs/common/components/hosts/tableUtils.js.map +1 -1
  85. package/build/cjs/common/components/storage/DisksTable.js +8 -8
  86. package/build/cjs/common/components/storage/DisksTable.js.map +1 -1
  87. package/build/cjs/common/components/storage/StorageDetail.js +3 -1
  88. package/build/cjs/common/components/storage/StorageDetail.js.map +1 -1
  89. package/build/cjs/common/components/ui/formik/validationSchemas.js +1 -1
  90. package/build/cjs/common/components/ui/formik/validationSchemas.js.map +1 -1
  91. package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationTableBase.js +1 -1
  92. package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationTableBase.js.map +1 -1
  93. package/build/cjs/ocm/components/clusterDetail/HostInventoryExpandable.js +3 -1
  94. package/build/cjs/ocm/components/clusterDetail/HostInventoryExpandable.js.map +1 -1
  95. package/build/cjs/ocm/components/hosts/HardwareStatus.js +3 -1
  96. package/build/cjs/ocm/components/hosts/HardwareStatus.js.map +1 -1
  97. package/build/cjs/ocm/components/hosts/NetworkingStatus.js +3 -1
  98. package/build/cjs/ocm/components/hosts/NetworkingStatus.js.map +1 -1
  99. package/lib/cim/components/Agent/AgentStatus.tsx +4 -3
  100. package/lib/cim/components/Agent/AgentTable.tsx +4 -1
  101. package/lib/cim/components/Agent/AgentsSelectionTable.tsx +4 -0
  102. package/lib/cim/components/Agent/BMCForm.tsx +23 -3
  103. package/lib/cim/components/Agent/tableUtils.tsx +75 -33
  104. package/lib/cim/components/ClusterDeployment/ClusterDeploymentDetailsTable.tsx +4 -1
  105. package/lib/cim/components/ClusterDeployment/ClusterDeploymentHostDiscoveryTable.tsx +21 -2
  106. package/lib/cim/components/ClusterDeployment/ClusterDeploymentHostsNetworkTable.tsx +18 -3
  107. package/lib/cim/components/Hypershift/HostedClusterWizard/HostsStep/HostsForm.tsx +35 -2
  108. package/lib/cim/components/Hypershift/HostedClusterWizard/HostsStep/HostsStep.tsx +2 -0
  109. package/lib/cim/components/Hypershift/HostedClusterWizard/HostsStep/types.ts +2 -0
  110. package/lib/cim/components/Hypershift/utils/status.tsx +3 -1
  111. package/lib/cim/components/InfraEnv/InfraEnvAgentTable.tsx +20 -7
  112. package/lib/cim/components/InfraEnv/InfraEnvHostsTabAgentsWarning.tsx +5 -2
  113. package/lib/cim/components/InfraEnv/InfraTableToolbar.tsx +21 -11
  114. package/lib/cim/components/helpers/agentStatus.tsx +17 -16
  115. package/lib/cim/components/helpers/agents.ts +3 -4
  116. package/lib/cim/components/helpers/status.ts +44 -24
  117. package/lib/cim/components/helpers/toAssisted.ts +3 -3
  118. package/lib/cim/components/modals/MassApproveAgentModal.tsx +13 -5
  119. package/lib/cim/components/modals/MassDeleteAgentModal.tsx +63 -56
  120. package/lib/common/components/clusterWizard/networkingSteps/ManagedNetworkingControlGroup.tsx +3 -3
  121. package/lib/common/components/hosts/HostRowDetail.tsx +20 -17
  122. package/lib/common/components/hosts/HostStatus.tsx +3 -1
  123. package/lib/common/components/hosts/status.tsx +227 -212
  124. package/lib/common/components/hosts/tableUtils.tsx +3 -3
  125. package/lib/common/components/storage/DisksTable.tsx +8 -8
  126. package/lib/common/components/storage/StorageDetail.tsx +4 -1
  127. package/lib/common/components/ui/formik/validationSchemas.ts +1 -1
  128. package/lib/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationTableBase.tsx +1 -1
  129. package/lib/ocm/components/clusterDetail/HostInventoryExpandable.tsx +3 -1
  130. package/lib/ocm/components/hosts/HardwareStatus.tsx +3 -1
  131. package/lib/ocm/components/hosts/NetworkingStatus.tsx +3 -1
  132. package/package.json +3 -3
@@ -16,17 +16,24 @@ import { AgentTableActions, ClusterDeploymentWizardStepsType } from '../ClusterD
16
16
  import { hostActionResolver } from '../../../common/components/hosts/tableUtils';
17
17
  import { getAgentClusterInstallOfAgent, getAIHosts, getInfraEnvNameOfAgent } from '../helpers';
18
18
  import { isInstallationInProgress } from '../ClusterDeployment/helpers';
19
- import { AGENT_BMH_NAME_LABEL_KEY } from '../common';
19
+ import { AGENT_BMH_NAME_LABEL_KEY, INFRAENV_GENERATED_AI_FLOW } from '../common';
20
20
  import { BareMetalHostK8sResource } from '../../types/k8s/bare-metal-host';
21
21
  import BMHStatus from './BMHStatus';
22
- import { getAgentStatus, getBMHStatus, getWizardStepAgentStatus } from '../helpers/status';
22
+ import {
23
+ getAgentStatus,
24
+ getAgentStatusKey,
25
+ getBMHStatus,
26
+ getBMHStatusKey,
27
+ getWizardStepAgentStatus,
28
+ } from '../helpers/status';
23
29
  import { filterByHostname } from '../../../common/components/hosts/utils';
24
- import { agentStatus, bmhStatus } from '../helpers/agentStatus';
30
+ import { agentStatus } from '../helpers/agentStatus';
25
31
  import noop from 'lodash-es/noop.js';
26
32
  import { useTranslation } from '../../../common/hooks/use-translation-wrapper';
27
33
  import { TFunction } from 'i18next';
28
34
  import { AgentMachineK8sResource } from '../Hypershift/types';
29
35
  import { Host } from '@openshift-assisted/types/assisted-installer-service';
36
+ import { HostStatus } from '../../../common/components/hosts/types';
30
37
 
31
38
  export const agentHostnameColumn = (
32
39
  t: TFunction,
@@ -117,7 +124,9 @@ export const discoveryTypeColumn = (
117
124
 
118
125
  type AgentStatusColumnProps = {
119
126
  agents: AgentK8sResource[];
127
+ agentStatuses: HostStatus<string>;
120
128
  bareMetalHosts?: BareMetalHostK8sResource[];
129
+ bmhStatuses?: HostStatus<string>;
121
130
  onEditHostname?: AgentTableActions['onEditHost'];
122
131
  onApprove?: AgentTableActions['onApprove'];
123
132
  wizardStepId?: ClusterDeploymentWizardStepsType;
@@ -127,7 +136,9 @@ type AgentStatusColumnProps = {
127
136
 
128
137
  export const agentStatusColumn = ({
129
138
  agents,
139
+ agentStatuses,
130
140
  bareMetalHosts,
141
+ bmhStatuses,
131
142
  onEditHostname,
132
143
  onApprove,
133
144
  wizardStepId,
@@ -158,8 +169,8 @@ export const agentStatusColumn = ({
158
169
  isDay2={isDay2}
159
170
  />
160
171
  );
161
- } else if (bmh) {
162
- bmhStatus = getBMHStatus(bmh);
172
+ } else if (bmh && bmhStatuses) {
173
+ bmhStatus = getBMHStatus(bmh, bmhStatuses);
163
174
  title = <BMHStatus bmhStatus={bmhStatus} />;
164
175
  }
165
176
 
@@ -169,7 +180,7 @@ export const agentStatusColumn = ({
169
180
  sortableValue: agent
170
181
  ? wizardStepId
171
182
  ? getWizardStepAgentStatus(agent, wizardStepId, t).status.title
172
- : getAgentStatus(agent).status.title
183
+ : getAgentStatus(agent, agentStatuses).status.title
173
184
  : bmhStatus?.state.title || '',
174
185
  };
175
186
  },
@@ -254,11 +265,7 @@ export const infraEnvColumn = (agents: AgentK8sResource[], t: TFunction): TableR
254
265
  };
255
266
 
256
267
  export const canEditBMH = (bmh: BareMetalHostK8sResource, t: TFunction): ActionCheck => {
257
- const canEdit = [
258
- bmhStatus.deprovisioning.key,
259
- bmhStatus.pending.key,
260
- bmhStatus.registering.key,
261
- ].includes(getBMHStatus(bmh).state.key);
268
+ const canEdit = ['deprovisioning', 'pending', 'registering'].includes(getBMHStatusKey(bmh) || '');
262
269
 
263
270
  return [
264
271
  canEdit,
@@ -270,8 +277,12 @@ export const canEditBMH = (bmh: BareMetalHostK8sResource, t: TFunction): ActionC
270
277
  ];
271
278
  };
272
279
 
273
- export const canEditAgent = (agent: AgentK8sResource, t: TFunction): ActionCheck => {
274
- const enabled = getAgentStatus(agent).status.category !== 'Installation related';
280
+ export const canEditAgent = (
281
+ agent: AgentK8sResource,
282
+ agentStatuses: HostStatus<string>,
283
+ t: TFunction,
284
+ ): ActionCheck => {
285
+ const enabled = getAgentStatus(agent, agentStatuses).status.category !== 'Installation related';
275
286
  return [
276
287
  enabled,
277
288
  enabled
@@ -283,13 +294,14 @@ export const canEditAgent = (agent: AgentK8sResource, t: TFunction): ActionCheck
283
294
  export const canChangeHostname =
284
295
  (
285
296
  agents: AgentK8sResource[],
297
+ agentStatuses: HostStatus<string>,
286
298
  bareMetalHosts: BareMetalHostK8sResource[],
287
299
  t: TFunction,
288
300
  ): ((h: Host) => ActionCheck) =>
289
301
  (h: Host) => {
290
302
  const agent = agents.find((a) => a.metadata?.uid === h.id);
291
303
  if (agent) {
292
- return canEditAgent(agent, t);
304
+ return canEditAgent(agent, agentStatuses, t);
293
305
  }
294
306
  const bmh = bareMetalHosts.find((bmh) => bmh.metadata?.uid === h.id);
295
307
  if (bmh) {
@@ -307,7 +319,7 @@ export const canUnbindAgent = (
307
319
  return [false, t('ai:The agent is not bound to a cluster.')];
308
320
  }
309
321
 
310
- const { status } = getAgentStatus(agent);
322
+ const statusKey = getAgentStatusKey(agent);
311
323
  if (
312
324
  [
313
325
  'preparing-for-installation',
@@ -315,13 +327,13 @@ export const canUnbindAgent = (
315
327
  'installing-in-progress',
316
328
  'installing-pending-user-action',
317
329
  'resetting-pending-user-action',
318
- ].includes(status.key)
330
+ ].includes(statusKey)
319
331
  ) {
320
332
  return [false, t('ai:It is not possible to remove a host which is being installed.')];
321
333
  }
322
334
 
323
335
  if (
324
- ['installed', 'error', 'cancelled'].includes(status.key) &&
336
+ ['installed', 'error', 'cancelled'].includes(statusKey) &&
325
337
  (agent.status?.role === 'master' || agent.status?.role === 'bootstrap')
326
338
  ) {
327
339
  return [
@@ -343,11 +355,23 @@ export const canUnbindAgent = (
343
355
  }
344
356
  }
345
357
 
358
+ if (
359
+ !agent.metadata?.labels?.hasOwnProperty(AGENT_BMH_NAME_LABEL_KEY) &&
360
+ agent.metadata?.labels?.hasOwnProperty(INFRAENV_GENERATED_AI_FLOW) &&
361
+ !!agent.spec.clusterDeploymentName
362
+ ) {
363
+ return [false, t('ai:It is not possible to remove this node from the cluster.')];
364
+ }
365
+
346
366
  return [true, undefined];
347
367
  };
348
368
 
349
- const canDeleteAgent = (agent: AgentK8sResource, t: TFunction): ActionCheck => {
350
- const enabled = getAgentStatus(agent).status.category !== 'Installation related';
369
+ const canDeleteAgent = (
370
+ agent: AgentK8sResource,
371
+ agentStatuses: HostStatus<string>,
372
+ t: TFunction,
373
+ ): ActionCheck => {
374
+ const enabled = getAgentStatus(agent, agentStatuses).status.category !== 'Installation related';
351
375
 
352
376
  return [
353
377
  enabled,
@@ -378,6 +402,7 @@ export const useAgentsTable = (
378
402
  onSetInstallationDiskId,
379
403
  } = tableActions || {};
380
404
  const { t } = useTranslation();
405
+ const agentStatuses = agentStatus(t);
381
406
  const [hosts, actions] = React.useMemo(
382
407
  (): [Host[], HostsTableActions] => [
383
408
  getAIHosts(agents, bmhs, infraEnv),
@@ -400,7 +425,7 @@ export const useAgentsTable = (
400
425
  if (!agent) {
401
426
  return false;
402
427
  }
403
- return canEditAgent(agent, t);
428
+ return canEditAgent(agent, agentStatuses, t);
404
429
  },
405
430
  onDeleteHost: onDeleteHost
406
431
  ? (host: Host) => {
@@ -414,7 +439,7 @@ export const useAgentsTable = (
414
439
  const bmh = bmhs?.find((a) => a.metadata?.uid === host.id);
415
440
 
416
441
  if (agent) {
417
- return canDeleteAgent(agent, t);
442
+ return canDeleteAgent(agent, agentStatuses, t);
418
443
  } else if (bmh) {
419
444
  return [true, undefined];
420
445
  }
@@ -480,6 +505,7 @@ export const useAgentsTable = (
480
505
  ],
481
506
  [
482
507
  agents,
508
+ t,
483
509
  bmhs,
484
510
  infraEnv,
485
511
  onEditHost,
@@ -489,7 +515,7 @@ export const useAgentsTable = (
489
515
  onSelect,
490
516
  onEditBMH,
491
517
  onUnbindHost,
492
- t,
518
+ agentStatuses,
493
519
  agentClusterInstalls,
494
520
  ],
495
521
  );
@@ -500,14 +526,15 @@ export const useAgentsTable = (
500
526
  const filterByStatus = (
501
527
  hosts: Host[],
502
528
  agents: AgentK8sResource[],
529
+ agentStatuses: HostStatus<string>,
503
530
  bareMetalHosts: BareMetalHostK8sResource[],
504
531
  statusFilter: string[],
505
532
  ) => {
506
533
  if (!statusFilter?.length) {
507
534
  return hosts;
508
535
  }
509
- const statusKeys = Object.keys(agentStatus).filter((k) =>
510
- statusFilter.includes(agentStatus[k].title),
536
+ const statusKeys = Object.keys(agentStatuses).filter((k) =>
537
+ statusFilter.includes(agentStatuses[k].title),
511
538
  );
512
539
  return hosts.filter((h) => {
513
540
  const agent = agents.find((a) => a.metadata?.uid === h.id);
@@ -516,10 +543,9 @@ const filterByStatus = (
516
543
  if (!bmh) {
517
544
  return false;
518
545
  }
519
- const bmhStatus = getBMHStatus(bmh);
520
- return statusKeys.includes(bmhStatus.state.key);
546
+ return statusKeys.includes(getBMHStatusKey(bmh) || '');
521
547
  }
522
- const { status } = getAgentStatus(agent);
548
+ const { status } = getAgentStatus(agent, agentStatuses);
523
549
  return statusKeys.includes(status.key);
524
550
  });
525
551
  };
@@ -527,44 +553,60 @@ const filterByStatus = (
527
553
  export const filterHosts = (
528
554
  hosts: Host[],
529
555
  agents: AgentK8sResource[],
556
+ agentStatuses: HostStatus<string>,
530
557
  bareMetalHosts: BareMetalHostK8sResource[],
531
558
  hostnameFilter: string | undefined,
532
559
  statusFilter: string[],
533
560
  ) => {
534
561
  const byHostname = filterByHostname(hosts, hostnameFilter);
535
- const byStatus = filterByStatus(byHostname, agents, bareMetalHosts, statusFilter);
562
+ const byStatus = filterByStatus(byHostname, agents, agentStatuses, bareMetalHosts, statusFilter);
536
563
 
537
564
  return byStatus;
538
565
  };
539
566
 
540
567
  type UseAgentsFilterArgs = {
541
568
  agents: AgentK8sResource[];
569
+ agentStatuses: HostStatus<string>;
542
570
  bmhs: BareMetalHostK8sResource[];
571
+ bmhStatuses: HostStatus<string>;
543
572
  hosts: Host[];
544
573
  };
545
574
 
546
575
  export type StatusCount = Record<string, number>;
547
576
 
548
- export const useAgentsFilter = ({ agents, bmhs, hosts }: UseAgentsFilterArgs) => {
577
+ export const useAgentsFilter = ({
578
+ agents,
579
+ agentStatuses,
580
+ bmhs,
581
+ bmhStatuses,
582
+ hosts,
583
+ }: UseAgentsFilterArgs) => {
549
584
  const [hostnameFilter, setHostnameFilter] = React.useState<string>();
550
585
  const [statusFilter, setStatusFilter] = React.useState<string[]>([]);
551
586
  const statusCount = Object.keys(agentStatus).reduce((acc, curr) => {
552
- acc[agentStatus[curr].title] = 0;
587
+ acc[agentStatuses[curr].title] = 0;
553
588
  return acc;
554
589
  }, {} as StatusCount);
555
590
  hosts.forEach((host) => {
556
591
  const agent = agents.find((a) => a.metadata?.uid === host.id);
557
592
  const bmh = bmhs.find((bmh) => bmh.metadata?.uid === host.id);
558
593
  if (agent) {
559
- const { status } = getAgentStatus(agent);
594
+ const { status } = getAgentStatus(agent, agentStatuses);
560
595
  statusCount[status.title]++;
561
596
  } else if (bmh) {
562
- const { state } = getBMHStatus(bmh);
597
+ const { state } = getBMHStatus(bmh, bmhStatuses);
563
598
  statusCount[state.title]++;
564
599
  }
565
600
  });
566
601
 
567
- const filteredHosts = filterHosts(hosts, agents, bmhs, hostnameFilter, statusFilter);
602
+ const filteredHosts = filterHosts(
603
+ hosts,
604
+ agents,
605
+ agentStatuses,
606
+ bmhs,
607
+ hostnameFilter,
608
+ statusFilter,
609
+ );
568
610
 
569
611
  return {
570
612
  statusCount,
@@ -13,6 +13,7 @@ import {
13
13
  import HostsTable, { DefaultExpandComponent } from '../../../common/components/hosts/HostsTable';
14
14
  import { usePagination } from '../../../common/components/hosts/usePagination';
15
15
  import { useTranslation } from '../../../common/hooks/use-translation-wrapper';
16
+ import { agentStatus } from '../helpers/agentStatus';
16
17
 
17
18
  export const getAgentId = (agent: AgentK8sResource) => agent.metadata?.uid as string;
18
19
 
@@ -39,12 +40,14 @@ const ClusterDeploymentDetailsTable: React.FC<ClusterDeploymentDetailsTableProps
39
40
  const agentClusterInstalls = React.useMemo(() => [agentClusterInstall], [agentClusterInstall]);
40
41
  const [hosts, , actionResolver] = useAgentsTable({ agents, agentClusterInstalls });
41
42
  const { t } = useTranslation();
43
+ const agentStatuses = agentStatus(t);
42
44
  const content = React.useMemo(
43
45
  () => [
44
46
  hostnameColumn(t),
45
47
  roleColumn(t),
46
48
  agentStatusColumn({
47
49
  agents,
50
+ agentStatuses,
48
51
  t,
49
52
  }),
50
53
  infraEnvColumn(agents, t),
@@ -52,7 +55,7 @@ const ClusterDeploymentDetailsTable: React.FC<ClusterDeploymentDetailsTableProps
52
55
  memoryColumn(t),
53
56
  disksColumn(t),
54
57
  ],
55
- [agents, t],
58
+ [agentStatuses, agents, t],
56
59
  );
57
60
 
58
61
  const paginationProps = usePagination(agents.length);
@@ -34,6 +34,7 @@ import { usePagination } from '../../../common/components/hosts/usePagination';
34
34
  import { useTranslation } from '../../../common/hooks/use-translation-wrapper';
35
35
  import { ExpandComponent } from '../Agent/AgentsSelectionTable';
36
36
  import { HostsTableDetailContextProvider } from '../../../common/components/hosts/HostsTableDetailContext';
37
+ import { agentStatus, bmhStatus } from '../helpers/agentStatus';
37
38
 
38
39
  const ClusterDeploymentHostDiscoveryTable: React.FC<ClusterDeploymentHostDiscoveryTableProps> = ({
39
40
  agents,
@@ -53,7 +54,11 @@ const ClusterDeploymentHostDiscoveryTable: React.FC<ClusterDeploymentHostDiscove
53
54
  const [isMassChangeHostOpen, setMassChangeHostOpen] = React.useState(false);
54
55
  const [isMassApproveOpen, setMassApproveOpen] = React.useState(false);
55
56
  const [selectedHostIDs, setSelectedHostIDs] = React.useState<string[]>([]);
57
+
56
58
  const { t } = useTranslation();
59
+ const agentStatuses = agentStatus(t);
60
+ const bmhStatuses = bmhStatus(t);
61
+
57
62
  const onSelect = (host: Host, isSelected: boolean) => {
58
63
  if (isSelected) {
59
64
  setSelectedHostIDs([...selectedHostIDs, host.id]);
@@ -79,7 +84,9 @@ const ClusterDeploymentHostDiscoveryTable: React.FC<ClusterDeploymentHostDiscove
79
84
  ...(addAll ? [discoveryTypeColumn(agents, bareMetalHosts, t)] : []),
80
85
  agentStatusColumn({
81
86
  agents,
87
+ agentStatuses,
82
88
  bareMetalHosts,
89
+ bmhStatuses,
83
90
  onEditHostname: onEditHost,
84
91
  onApprove,
85
92
  wizardStepId: 'hosts-discovery',
@@ -90,7 +97,19 @@ const ClusterDeploymentHostDiscoveryTable: React.FC<ClusterDeploymentHostDiscove
90
97
  ? [discoveredAtColumn(t), cpuCoresColumn(t), memoryColumn(t), disksColumn(t)]
91
98
  : []),
92
99
  ],
93
- [agents, hostActions, bareMetalHosts, onApprove, onEditHost, addAll, t],
100
+ [
101
+ t,
102
+ hostActions.onEditHost,
103
+ hostActions.canEditRole,
104
+ hostActions.onEditRole,
105
+ addAll,
106
+ agents,
107
+ bareMetalHosts,
108
+ agentStatuses,
109
+ bmhStatuses,
110
+ onEditHost,
111
+ onApprove,
112
+ ],
94
113
  );
95
114
 
96
115
  const selectedAgents = agents.filter((a) => selectedHostIDs.includes(a.metadata?.uid || ''));
@@ -168,7 +187,7 @@ const ClusterDeploymentHostDiscoveryTable: React.FC<ClusterDeploymentHostDiscove
168
187
  selectedHostIDs={selectedHostIDs}
169
188
  onChangeHostname={onAgentChangeHostname}
170
189
  onClose={() => setMassChangeHostOpen(false)}
171
- canChangeHostname={canChangeHostname(agents, bareMetalHosts, t)}
190
+ canChangeHostname={canChangeHostname(agents, agentStatuses, bareMetalHosts, t)}
172
191
  />
173
192
  )}
174
193
  {isMassApproveOpen && (
@@ -20,6 +20,7 @@ import {
20
20
  import { usePagination } from '../../../common/components/hosts/usePagination';
21
21
  import { useTranslation } from '../../../common/hooks/use-translation-wrapper';
22
22
  import { Host } from '@openshift-assisted/types/assisted-installer-service';
23
+ import { agentStatus } from '../helpers/agentStatus';
23
24
 
24
25
  type ExpandComponentContextType = {
25
26
  onSetInstallationDiskId?: ClusterDeploymentHostsNetworkTableProps['onSetInstallationDiskId'];
@@ -79,6 +80,7 @@ const ClusterDeploymentHostsNetworkTable: React.FC<ClusterDeploymentHostsNetwork
79
80
  onSetInstallationDiskId,
80
81
  }) => {
81
82
  const { t } = useTranslation();
83
+ const agentStatuses = agentStatus(t);
82
84
  const cluster = React.useMemo(
83
85
  () => getAICluster({ clusterDeployment, agentClusterInstall, agents }),
84
86
  [clusterDeployment, agentClusterInstall, agents],
@@ -100,24 +102,37 @@ const ClusterDeploymentHostsNetworkTable: React.FC<ClusterDeploymentHostsNetwork
100
102
  hostnameColumn(t, hostActions.onEditHost, hosts),
101
103
  agentStatusColumn({
102
104
  agents,
105
+ agentStatuses,
103
106
  onEditHostname: onEditHost,
104
107
  wizardStepId: 'networking',
105
108
  t,
106
109
  }),
107
- activeNICColumn(cluster),
110
+ activeNICColumn(cluster, t),
108
111
  ]
109
112
  : [
110
113
  hostnameColumn(t, hostActions.onEditHost, hosts),
111
114
  roleColumn(t, hostActions.canEditRole, hostActions.onEditRole),
112
115
  agentStatusColumn({
113
116
  agents,
117
+ agentStatuses,
114
118
  onEditHostname: onEditHost,
115
119
  wizardStepId: 'networking',
116
120
  t,
117
121
  }),
118
- activeNICColumn(cluster),
122
+ activeNICColumn(cluster, t),
119
123
  ],
120
- [isSNOCluster, onEditHost, hosts, agents, hostActions, cluster, t],
124
+ [
125
+ isSNOCluster,
126
+ t,
127
+ hostActions.onEditHost,
128
+ hostActions.canEditRole,
129
+ hostActions.onEditRole,
130
+ hosts,
131
+ agents,
132
+ agentStatuses,
133
+ onEditHost,
134
+ cluster,
135
+ ],
121
136
  );
122
137
 
123
138
  const paginationProps = usePagination(hosts.length);
@@ -1,10 +1,10 @@
1
1
  import * as React from 'react';
2
2
  import { FieldArray, useFormikContext } from 'formik';
3
3
  import { PlusCircleIcon } from '@patternfly/react-icons';
4
- import { Alert, Button, Form, Grid, GridItem } from '@patternfly/react-core';
4
+ import { Alert, Button, Form, FormGroup, Grid, GridItem } from '@patternfly/react-core';
5
5
 
6
6
  import { useTranslation } from '../../../../../common/hooks/use-translation-wrapper';
7
- import { PopoverIcon, SelectField } from '../../../../../common';
7
+ import { PopoverIcon, RadioField, SelectField } from '../../../../../common';
8
8
  import { getRandomString } from '../../../../../common/utils';
9
9
  import { useTemptiflySync } from '../../hooks/useTemptiflySync';
10
10
 
@@ -42,6 +42,39 @@ const HostsForm: React.FC<HostsFormProps> = ({
42
42
  return (
43
43
  <Form>
44
44
  <Grid hasGutter>
45
+ <GridItem>
46
+ <FormGroup isInline label={<>{t('ai:Controller availability policy')}</>} isRequired>
47
+ <RadioField
48
+ name={'controllerAvailabilityPolicy'}
49
+ label={
50
+ <>
51
+ {t('ai:Highly available')}{' '}
52
+ <PopoverIcon
53
+ bodyContent={t(
54
+ 'ai:Highly available means components should be resilient to problems across fault boundaries as defined by the component to which the policy is attached. This usually means running critical workloads with 3 replicas and with little or no toleration of disruption of the component.',
55
+ )}
56
+ />
57
+ </>
58
+ }
59
+ value={'HighlyAvailable'}
60
+ />
61
+ <RadioField
62
+ name={'controllerAvailabilityPolicy'}
63
+ label={
64
+ <>
65
+ {t('ai:Single replica')}{' '}
66
+ <PopoverIcon
67
+ bodyContent={t(
68
+ 'ai:Single replica means components are not expected to be resilient to problems across most fault boundaries associated with high availability. This usually means running critical workloads with just 1 replica and with toleration of full disruption of the component.',
69
+ )}
70
+ />
71
+ </>
72
+ }
73
+ value={'SingleReplica'}
74
+ />
75
+ </FormGroup>
76
+ </GridItem>
77
+
45
78
  <GridItem>
46
79
  <SelectField
47
80
  label={t('ai:Namespace')}
@@ -51,6 +51,7 @@ const HostsStep: React.FC<HostsStepProps> = ({
51
51
  initNodePools,
52
52
  initReleaseImage,
53
53
  nodePools,
54
+ controllerAvailabilityPolicy,
54
55
  }) => {
55
56
  const { t } = useTranslation();
56
57
  const availableAgents = getAgentsForSelection(agents);
@@ -73,6 +74,7 @@ const HostsStep: React.FC<HostsStepProps> = ({
73
74
  <StackItem>
74
75
  <Formik<HostsFormValues>
75
76
  initialValues={{
77
+ controllerAvailabilityPolicy: controllerAvailabilityPolicy || 'HighlyAvailable',
76
78
  agentNamespace: initInfraEnv || infraEnvsWithAgents[0]?.metadata?.namespace || '',
77
79
  nodePools: initNodePools || [
78
80
  {
@@ -14,6 +14,7 @@ export type NodePoolFormValue = {
14
14
  };
15
15
 
16
16
  export type HostsFormValues = {
17
+ controllerAvailabilityPolicy: string;
17
18
  agentNamespace: string;
18
19
  nodePools: NodePoolFormValue[];
19
20
  };
@@ -33,4 +34,5 @@ export type HostsStepProps = {
33
34
  initInfraEnv?: string;
34
35
  initNodePools?: NodePoolFormValue[];
35
36
  nodePools: NodePoolK8sResource[];
37
+ controllerAvailabilityPolicy: string;
36
38
  };
@@ -9,6 +9,7 @@ import { AgentK8sResource } from '../../../types';
9
9
  import { getAgentStatus } from '../../helpers';
10
10
  import { NodePoolK8sResource } from '../types';
11
11
  import { TFunction } from 'i18next';
12
+ import { agentStatus } from '../../helpers/agentStatus';
12
13
 
13
14
  export type NodePoolStatus = {
14
15
  type: 'error' | 'pending' | 'ok' | 'warning';
@@ -31,7 +32,8 @@ export const getNodePoolStatus = (
31
32
  };
32
33
  }
33
34
 
34
- const agentStatuses = agents.map((a) => getAgentStatus(a));
35
+ const allAgentStatuses = agentStatus(t);
36
+ const agentStatuses = agents.map((a) => getAgentStatus(a, allAgentStatuses));
35
37
 
36
38
  const hasErrorAgents = agentStatuses.some(({ status }) => status.key === 'error');
37
39
 
@@ -37,6 +37,7 @@ import MassApproveAction from '../modals/MassApproveAction';
37
37
  import { usePagination } from '../../../common/components/hosts/usePagination';
38
38
  import InfraTableToolbar from './InfraTableToolbar';
39
39
  import { useTranslation } from '../../../common/hooks/use-translation-wrapper';
40
+ import { agentStatus, bmhStatus } from '../helpers/agentStatus';
40
41
 
41
42
  type NoFilterMatchStateProps = {
42
43
  onClearFilters: VoidFunction;
@@ -107,6 +108,8 @@ const InfraEnvAgentTable: React.FC<InfraEnvAgentTableProps> = ({
107
108
  },
108
109
  );
109
110
  const { t } = useTranslation();
111
+ const agentStatuses = agentStatus(t);
112
+ const bmhStatuses = bmhStatus(t);
110
113
  const {
111
114
  statusCount,
112
115
  hostnameFilter,
@@ -114,7 +117,13 @@ const InfraEnvAgentTable: React.FC<InfraEnvAgentTableProps> = ({
114
117
  setStatusFilter,
115
118
  statusFilter,
116
119
  filteredHosts: hosts,
117
- } = useAgentsFilter({ agents, bmhs: bareMetalHosts, hosts: allHosts });
120
+ } = useAgentsFilter({
121
+ agents,
122
+ agentStatuses,
123
+ bmhs: bareMetalHosts,
124
+ bmhStatuses,
125
+ hosts: allHosts,
126
+ });
118
127
 
119
128
  const content = React.useMemo(
120
129
  () =>
@@ -131,6 +140,7 @@ const InfraEnvAgentTable: React.FC<InfraEnvAgentTableProps> = ({
131
140
  discoveryTypeColumn(agents, bareMetalHosts, t),
132
141
  agentStatusColumn({
133
142
  agents,
143
+ agentStatuses,
134
144
  bareMetalHosts,
135
145
  onEditHostname: onEditHost,
136
146
  onApprove: onApprove,
@@ -143,15 +153,18 @@ const InfraEnvAgentTable: React.FC<InfraEnvAgentTableProps> = ({
143
153
  disksColumn(t),
144
154
  ].filter(Boolean),
145
155
  [
156
+ t,
146
157
  hosts,
147
158
  agents,
148
- agentMachines,
159
+ bareMetalHosts,
160
+ hostActions.onEditHost,
161
+ hostActions.canEditHostname,
162
+ hostActions.canEditBMH,
163
+ agentStatuses,
149
164
  onEditHost,
150
165
  onApprove,
166
+ agentMachines,
151
167
  getClusterDeploymentLink,
152
- hostActions,
153
- bareMetalHosts,
154
- t,
155
168
  ],
156
169
  );
157
170
 
@@ -162,7 +175,7 @@ const InfraEnvAgentTable: React.FC<InfraEnvAgentTableProps> = ({
162
175
 
163
176
  const canEditHostname =
164
177
  selectedBMHs.some((bmh) => canEditBMH(bmh, t)[0]) ||
165
- selectedAgents.some((a) => canEditAgent(a, t)[0]);
178
+ selectedAgents.some((a) => canEditAgent(a, agentStatuses, t)[0]);
166
179
 
167
180
  const massActions = [
168
181
  <DropdownItem
@@ -252,7 +265,7 @@ const InfraEnvAgentTable: React.FC<InfraEnvAgentTableProps> = ({
252
265
  selectedHostIDs={selectedHostIDs}
253
266
  onChangeHostname={onAgentChangeHostname}
254
267
  onClose={() => setMassChangeHostOpen(false)}
255
- canChangeHostname={canChangeHostname(agents, bareMetalHosts, t)}
268
+ canChangeHostname={canChangeHostname(agents, agentStatuses, bareMetalHosts, t)}
256
269
  />
257
270
  )}
258
271
  {isMassDeleteOpen && (
@@ -6,6 +6,7 @@ import { AgentK8sResource, BareMetalHostK8sResource } from '../../types';
6
6
  import { AGENT_BMH_NAME_LABEL_KEY } from '../common';
7
7
  import { Tooltip } from '@patternfly/react-core';
8
8
  import { useTranslation } from '../../../common/hooks/use-translation-wrapper';
9
+ import { agentStatus, bmhStatus } from '../helpers/agentStatus';
9
10
 
10
11
  export type InfraEnvHostsTabAgentsWarning = {
11
12
  infraAgents: AgentK8sResource[];
@@ -26,9 +27,11 @@ const InfraEnvHostsTabAgentsWarning: React.FC<InfraEnvHostsTabAgentsWarning> = (
26
27
  const bmhsWithoutAgents = infraBMHs.filter((bmh) =>
27
28
  agentsBMHNames.includes(bmh.metadata?.name || ''),
28
29
  );
30
+ const agentStatuses = agentStatus(t);
31
+ const bmhStatuses = bmhStatus(t);
29
32
 
30
- const agentStates = infraAgents.map((agent) => getAgentStatus(agent, true).status);
31
- const bmhStates = bmhsWithoutAgents.map((bmh) => getBMHStatus(bmh).state);
33
+ const agentStates = infraAgents.map((agent) => getAgentStatus(agent, agentStatuses, true).status);
34
+ const bmhStates = bmhsWithoutAgents.map((bmh) => getBMHStatus(bmh, bmhStatuses).state);
32
35
 
33
36
  const hostStates = [...agentStates, ...bmhStates];
34
37