diff --git a/pkg/harvester/components/health/__tests__/health.test.js b/pkg/harvester/components/health/__tests__/health.test.js
index 450ff136..7a406fff 100644
--- a/pkg/harvester/components/health/__tests__/health.test.js
+++ b/pkg/harvester/components/health/__tests__/health.test.js
@@ -156,7 +156,9 @@ const actionsOf = (props = {}, storeProps = {}) => {
};
};
-const mountRuleModal = ({ rule, mode, save = () => {} } = {}) => {
+const mountRuleModal = ({
+ rule, mode, save = () => {}, row = CHECK
+} = {}) => {
createRule.mockClear();
cloneRule.mockClear();
saveRule.mockReset().mockImplementation(save);
@@ -167,7 +169,7 @@ const mountRuleModal = ({ rule, mode, save = () => {} } = {}) => {
const w = vtuMount(IgnoreRuleModal, {
...opts(),
props: {
- row: CHECK, rule, mode, modal: { show: true, onClose }
+ row, rule, mode, modal: { show: true, onClose }
},
});
@@ -408,6 +410,10 @@ describe('health components', () => {
it('names the rule of a check after it', () => {
expect(ignoreRuleName('harvester-controller-vmimage', 'ImageRetryLimitExceeded')).toBe('harvester-controller-vmimage.imageretrylimitexceeded');
});
+ it('turns what a name can not have in a check into hyphens', () => {
+ expect(ignoreRuleName('harvester-controller-schedulevmbackup', 'Proactive Schedule Suspend')).toBe('harvester-controller-schedulevmbackup.proactive-schedule-suspend');
+ expect(ignoreRuleName('h', ' Reach_Max Failure! ')).toBe('h.reach-max-failure');
+ });
it('tells the ignored resources apart, and all of them when the check is ignored', () => {
const table = { props: ['rows'], template: '
' };
const row = {
@@ -634,6 +640,15 @@ describe('health components', () => {
expect(createRule.mock.calls[0][1].metadata).toStrictEqual({ name: 'h.a', labels: { 'health.harvesterhci.io/source': 'user' } });
});
+ it('gives a check with spaces a valid name, and keeps the check as it is', async() => {
+ const { confirm } = mountRuleModal({ row: { ...CHECK, checkName: 'Proactive Schedule Suspend' } });
+
+ await confirm().trigger('click');
+ await flushPromises();
+
+ expect(createRule.mock.calls[0][1].metadata.name).toBe('h.proactive-schedule-suspend');
+ expect(newRule.spec.checkKey).toBe('Proactive Schedule Suspend');
+ });
it('says when the rule will expire, from 7 days on', async() => {
const {
confirm, duration, currentExpiry, newExpiry
diff --git a/pkg/harvester/utils/component-health.js b/pkg/harvester/utils/component-health.js
index 030a9d46..0b5e4a43 100644
--- a/pkg/harvester/utils/component-health.js
+++ b/pkg/harvester/utils/component-health.js
@@ -86,9 +86,12 @@ export function ignoredCounts(checks) {
}, { checks: 0, resources: 0 });
}
-// the UI keeps one rule per check under this name, so Kubernetes refuses a second one for the same check
+// the UI keeps one rule per check under this name, so Kubernetes refuses a second one for the same check.
+// Some checks are named after a condition reason with spaces, like "Proactive Schedule Suspend", which a name can't have
export function ignoreRuleName(componentHealthName, checkName) {
- return `${ componentHealthName }.${ checkName.toLowerCase() }`;
+ const check = checkName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
+
+ return `${ componentHealthName }.${ check }`;
}
export function affectedResourceKind(row) {