Skip to content

Commit 9fadfde

Browse files
Fixed ingress setting order (#17136)
1 parent 541f385 commit 9fadfde

4 files changed

Lines changed: 192 additions & 3 deletions

File tree

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
import { mount } from '@vue/test-utils';
2+
import Ingress from '@shell/edit/provisioning.cattle.io.cluster/tabs/Ingress.vue';
3+
import { _EDIT } from '@shell/config/query-params';
4+
import { INGRESS_DUAL, TRAEFIK, INGRESS_NGINX, INGRESS_NONE } from '@shell/edit/provisioning.cattle.io.cluster/shared';
5+
6+
jest.mock('vuex', () => ({
7+
useStore: () => ({ getters: { 'i18n/t': (key: string) => key } }),
8+
mapGetters: () => ({ t: (key: string) => key })
9+
}));
10+
11+
jest.mock('@shell/edit/provisioning.cattle.io.cluster/shared', () => ({
12+
13+
INGRESS_NGINX: 'ingress-nginx',
14+
TRAEFIK: 'traefik',
15+
INGRESS_DUAL: 'dual',
16+
INGRESS_NONE: 'none',
17+
INGRESS_OPTIONS: [{
18+
id: 'traefik',
19+
image: { src: '', alt: 'Traefik' },
20+
header: { title: { key: 'cluster.ingress.traefik.header' } },
21+
subHeader: { label: { key: 'cluster.ingress.recommended' } },
22+
content: { key: 'cluster.ingress.traefik.content' },
23+
doc: { url: 'https://docs.rke2.io/networking/networking_services?_highlight=ingress#ingress-controller' }
24+
},
25+
{
26+
id: 'ingress-nginx',
27+
image: { src: '', alt: 'NGINX' },
28+
header: { title: { key: 'cluster.ingress.nginx.header' } },
29+
subHeader: { label: { key: 'cluster.ingress.legacy' } },
30+
content: { key: 'cluster.ingress.nginx.content' },
31+
doc: { url: 'https://www.kubernetes.dev/blog/2025/11/12/ingress-nginx-retirement/' }
32+
},
33+
{
34+
id: 'dual',
35+
header: { title: { key: 'cluster.ingress.dual.header' } },
36+
subHeader: { label: { key: 'cluster.ingress.migration' } },
37+
content: { key: 'cluster.ingress.dual.content' }
38+
}],
39+
INGRESS_MIGRATION_KB_LINK: 'mock-link',
40+
INGRESS_CONTROLLER_CLASS_MIGRATION: 'rke2.cattle.io/ingress-nginx-migration',
41+
INGRESS_CLASS_DEFAULT: 'rke2.cattle.io/ingress-nginx-default',
42+
INGRESS_CONTROLLER_CLASS_DEFAULT: 'rke2.cattle.io/ingress-nginx-controller-default',
43+
INGRESS_CLASS_MIGRATION: 'rke2.cattle.io/ingress-nginx-migration'
44+
}));
45+
46+
describe('ingress.vue', () => {
47+
const defaultProps = {
48+
mode: _EDIT,
49+
value: INGRESS_NONE,
50+
nginxSupported: true,
51+
traefikSupported: true,
52+
nginxChart: 'rancher-ingress-nginx',
53+
traefikChart: 'traefik',
54+
userChartValues: {},
55+
versionInfo: {
56+
'rancher-ingress-nginx': { values: {} },
57+
traefik: { values: {} }
58+
}
59+
};
60+
61+
const createWrapper = (props = {}) => mount(Ingress, {
62+
props: { ...defaultProps, ...props },
63+
global: {
64+
stubs: {
65+
Checkbox: true,
66+
Banner: true,
67+
IngressCards: true,
68+
IngressConfiguration: true,
69+
YamlEditor: true,
70+
RichTranslation: true
71+
}
72+
}
73+
});
74+
75+
it('renders checkbox to enable/disable ingress', () => {
76+
const wrapper = createWrapper();
77+
const checkbox = wrapper.findComponent({ name: 'Checkbox' });
78+
79+
expect(checkbox.exists()).toBe(true);
80+
});
81+
82+
it('emits update:value with INGRESS_NONE when ingress is disabled', async() => {
83+
const wrapper = createWrapper({ value: TRAEFIK });
84+
const checkbox = wrapper.findComponent({ name: 'Checkbox' });
85+
86+
await checkbox.vm.$emit('update:value', false);
87+
88+
expect(wrapper.emitted('update:value')).toBeTruthy();
89+
expect(wrapper.emitted('update:value')?.[0]).toStrictEqual([INGRESS_NONE]);
90+
});
91+
92+
it('emits update:value with TRAEFIK when ingress is enabled and traefik is supported', async() => {
93+
const wrapper = createWrapper({ value: INGRESS_NONE });
94+
const checkbox = wrapper.findComponent({ name: 'Checkbox' });
95+
96+
await checkbox.vm.$emit('update:value', true);
97+
98+
expect(wrapper.emitted('update:value')).toBeTruthy();
99+
expect(wrapper.emitted('update:value')?.[0]).toStrictEqual([TRAEFIK]);
100+
});
101+
102+
it('emits update:value with INGRESS_NGINX when ingress is enabled, traefik is NOT supported, and nginx IS supported', async() => {
103+
const wrapper = createWrapper({ value: INGRESS_NONE, traefikSupported: false });
104+
const checkbox = wrapper.findComponent({ name: 'Checkbox' });
105+
106+
await checkbox.vm.$emit('update:value', true);
107+
108+
expect(wrapper.emitted('update:value')).toBeTruthy();
109+
expect(wrapper.emitted('update:value')?.[0]).toStrictEqual([INGRESS_NGINX]);
110+
});
111+
112+
it('selectIngress emits [INGRESS_NGINX, TRAEFIK] string value when INGRESS_DUAL is selected and previous value was ingress-nginx', () => {
113+
const wrapper = createWrapper({ value: INGRESS_NGINX, originalIngressController: INGRESS_NGINX });
114+
const ingressCards = wrapper.findComponent({ name: 'IngressCards' });
115+
116+
ingressCards.vm.$emit('select', INGRESS_DUAL);
117+
118+
expect(wrapper.emitted('update:value')).toBeTruthy();
119+
expect(wrapper.emitted('update:value')?.[0]).toStrictEqual([[INGRESS_NGINX, TRAEFIK]]);
120+
});
121+
122+
it('selectIngress emits [TRAEFIK, INGRESS_NGINX] string value when INGRESS_DUAL is selected and previous value was traefik', () => {
123+
const wrapper = createWrapper({ value: TRAEFIK, originalIngressController: TRAEFIK });
124+
const ingressCards = wrapper.findComponent({ name: 'IngressCards' });
125+
126+
ingressCards.vm.$emit('select', INGRESS_DUAL);
127+
128+
expect(wrapper.emitted('update:value')).toBeTruthy();
129+
expect(wrapper.emitted('update:value')?.[0]).toStrictEqual([[TRAEFIK, INGRESS_NGINX]]);
130+
});
131+
132+
it('selectIngress emits [TRAEFIK, INGRESS_NGINX] string value when INGRESS_DUAL is selected and value went traefik -> nginx -> dual', () => {
133+
const wrapper = createWrapper({ value: TRAEFIK, originalIngressController: TRAEFIK });
134+
const ingressCards = wrapper.findComponent({ name: 'IngressCards' });
135+
136+
ingressCards.vm.$emit('select', INGRESS_NGINX);
137+
expect(wrapper.emitted('update:value')).toBeTruthy();
138+
expect(wrapper.emitted('update:value')?.[0]).toStrictEqual([INGRESS_NGINX]);
139+
140+
ingressCards.vm.$emit('select', INGRESS_DUAL);
141+
142+
expect(wrapper.emitted('update:value')).toBeTruthy();
143+
expect(wrapper.emitted('update:value')?.[1]).toStrictEqual([[TRAEFIK, INGRESS_NGINX]]);
144+
});
145+
146+
it('selectIngress emits string value when a single ingress is selected', () => {
147+
const wrapper = createWrapper({ value: TRAEFIK });
148+
const ingressCards = wrapper.findComponent({ name: 'IngressCards' });
149+
150+
ingressCards.vm.$emit('select', INGRESS_NGINX);
151+
152+
expect(wrapper.emitted('update:value')).toBeTruthy();
153+
expect(wrapper.emitted('update:value')?.[0]).toStrictEqual([INGRESS_NGINX]);
154+
});
155+
156+
it('renders IngressConfiguration when versionInfo contains chart values', () => {
157+
const wrapper = createWrapper({ value: TRAEFIK });
158+
const config = wrapper.findComponent({ name: 'IngressConfiguration' });
159+
160+
expect(config.exists()).toBe(true);
161+
});
162+
163+
it('toggles advanced configuration visibility and renders YamlEditor', async() => {
164+
const wrapper = createWrapper({ value: TRAEFIK });
165+
166+
expect(wrapper.findComponent({ name: 'YamlEditor' }).exists()).toBe(false);
167+
168+
const advancedButton = wrapper.find('.advanced-toggle');
169+
170+
await advancedButton.trigger('click');
171+
172+
const yamlEditor = wrapper.find('[data-testid="traefik-yaml-editor"]');
173+
174+
expect(yamlEditor.exists()).toBe(true);
175+
});
176+
});

shell/edit/provisioning.cattle.io.cluster/rke2.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,8 @@ export default {
297297
originalKubeVersion: null,
298298
isEmpty,
299299
AGENT_CONFIGURATION_TYPES,
300-
basicsValid: true
300+
basicsValid: true,
301+
originalIngressController: this.value.spec.rkeConfig.machineGlobalConfig?.[INGRESS_CONTROLLER] || INGRESS_NONE,
301302
};
302303
},
303304

@@ -2593,6 +2594,7 @@ export default {
25932594
:is-azure-provider-unsupported="isAzureProviderUnsupported"
25942595
:can-azure-migrate-on-edit="canAzureMigrateOnEdit"
25952596
:has-some-ipv6-pools="hasOnlyIpv6Pools"
2597+
:original-ingress-controller="originalIngressController"
25962598
@update:value="$emit('input', $event)"
25972599
@cilium-values-changed="handleCiliumValuesChanged"
25982600
@enabled-system-services-changed="handleEnabledSystemServicesChanged"

shell/edit/provisioning.cattle.io.cluster/tabs/Basics.vue

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ export default {
120120
canAzureMigrateOnEdit: {
121121
type: Boolean,
122122
required: true
123+
},
124+
originalIngressController: {
125+
type: [String, Array],
126+
required: false,
127+
default: INGRESS_NONE
123128
}
124129
},
125130
@@ -699,6 +704,7 @@ export default {
699704
:traefik-chart="traefikChart"
700705
:user-chart-values="userChartValues"
701706
:version-info="versionInfo"
707+
:original-ingress-controller="originalIngressController"
702708
@update-values="(name, val) => $emit('update-values', name, val)"
703709
@error="$emit('error', $event)"
704710
@yaml-validation-changed="e => $emit('yaml-validation-changed', e)"

shell/edit/provisioning.cattle.io.cluster/tabs/Ingress.vue

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ interface Props {
2424
traefikChart: string;
2525
userChartValues: any;
2626
versionInfo: any;
27+
originalIngressController?: string | string[];
2728
}
2829
const {
2930
mode = _CREATE,
@@ -33,7 +34,8 @@ const {
3334
nginxSupported,
3435
traefikSupported,
3536
userChartValues,
36-
versionInfo
37+
versionInfo,
38+
originalIngressController = INGRESS_NONE
3739
} = defineProps<Props>();
3840
3941
const emit = defineEmits(['update:value', 'error', 'config-validation-changed', 'yaml-validation-changed', 'update-values']);
@@ -179,7 +181,10 @@ const compatibilityMode = computed({
179181
180182
function selectIngress(id: string) {
181183
if ( id === INGRESS_DUAL) {
182-
emit('update:value', [TRAEFIK, INGRESS_NGINX]);
184+
const newValue: string | string[] = !Array.isArray(originalIngressController) ? (originalIngressController === TRAEFIK ? [TRAEFIK, INGRESS_NGINX] : [INGRESS_NGINX, TRAEFIK]) : originalIngressController;
185+
186+
emit('update:value', newValue);
187+
183188
preconfigureTraefik();
184189
} else {
185190
emit('update:value', id);

0 commit comments

Comments
 (0)