fix: keep the ignore rule name valid when the check has spaces (#1234)

Backup schedule checks are named after the schedule's condition reason,
such as "Proactive Schedule Suspend". The rule name used it lowercased,
spaces included, so Kubernetes refused it and the check could not be
ignored. Turn whatever a name can't have into hyphens. The rule keeps
the check as it is in its spec, which is what the controller matches.

Signed-off-by: Marcelo Fukumoto <marcelo.fukumoto@suse.com>
This commit is contained in:
Marcelo Fukumoto
2026-11-10 12:21:30 +01:00
committed by GitHub
parent 784c22e27e
commit ee915249ce
2 changed files with 22 additions and 4 deletions
@@ -156,7 +156,9 @@ const actionsOf = (props = {}, storeProps = {}) => {
}; };
}; };
const mountRuleModal = ({ rule, mode, save = () => {} } = {}) => { const mountRuleModal = ({
rule, mode, save = () => {}, row = CHECK
} = {}) => {
createRule.mockClear(); createRule.mockClear();
cloneRule.mockClear(); cloneRule.mockClear();
saveRule.mockReset().mockImplementation(save); saveRule.mockReset().mockImplementation(save);
@@ -167,7 +169,7 @@ const mountRuleModal = ({ rule, mode, save = () => {} } = {}) => {
const w = vtuMount(IgnoreRuleModal, { const w = vtuMount(IgnoreRuleModal, {
...opts(), ...opts(),
props: { 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', () => { it('names the rule of a check after it', () => {
expect(ignoreRuleName('harvester-controller-vmimage', 'ImageRetryLimitExceeded')).toBe('harvester-controller-vmimage.imageretrylimitexceeded'); 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', () => { it('tells the ignored resources apart, and all of them when the check is ignored', () => {
const table = { props: ['rows'], template: '<div><slot name="cell:severity" :row="rows[0]" /><slot name="cell:affectedCount" :row="rows[0]" :value="2" /></div>' }; const table = { props: ['rows'], template: '<div><slot name="cell:severity" :row="rows[0]" /><slot name="cell:affectedCount" :row="rows[0]" :value="2" /></div>' };
const row = { 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' } }); 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() => { it('says when the rule will expire, from 7 days on', async() => {
const { const {
confirm, duration, currentExpiry, newExpiry confirm, duration, currentExpiry, newExpiry
+5 -2
View File
@@ -86,9 +86,12 @@ export function ignoredCounts(checks) {
}, { checks: 0, resources: 0 }); }, { 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) { 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) { export function affectedResourceKind(row) {