@@ -122,6 +122,7 @@ export default {
diff --git a/shell/dialog/__tests__/InstallExtensionDialog.test.ts b/shell/dialog/__tests__/InstallExtensionDialog.test.ts
new file mode 100644
index 0000000000..48c521ca66
--- /dev/null
+++ b/shell/dialog/__tests__/InstallExtensionDialog.test.ts
@@ -0,0 +1,111 @@
+import { shallowMount, VueWrapper } from '@vue/test-utils';
+import InstallExtensionDialog from '@shell/dialog/InstallExtensionDialog.vue';
+
+jest.mock('@shell/config/uiplugins', () => ({
+ ...jest.requireActual('@shell/config/uiplugins'),
+ isChartVersionHigher: jest.fn((v1: string, v2: string) => v1 > v2),
+}));
+
+const t = (key: string): string => key;
+
+describe('component: InstallExtensionDialog', () => {
+ let wrapper: VueWrapper
;
+
+ const mountComponent = (propsData = {}) => {
+ const store = { dispatch: () => Promise.resolve() };
+
+ const defaultProps = {
+ plugin: { installableVersions: [] },
+ action: 'install',
+ updateStatus: jest.fn(),
+ closed: jest.fn(),
+ };
+
+ return shallowMount(InstallExtensionDialog, {
+ propsData: {
+ ...defaultProps,
+ ...propsData,
+ },
+ global: {
+ mocks: {
+ $store: store,
+ t,
+ },
+ }
+ });
+ };
+
+ describe('fetch', () => {
+ it('should set currentVersion if plugin is installed', async() => {
+ wrapper = mountComponent({ plugin: { installed: true, installedVersion: '1.0.0' } });
+ await wrapper.vm.$options.fetch.call(wrapper.vm);
+ expect(wrapper.vm.currentVersion).toBe('1.0.0');
+ });
+
+ it('should set version from initialVersion if provided', async() => {
+ wrapper = mountComponent({ initialVersion: '1.2.3', plugin: { installed: false } });
+ await wrapper.vm.$options.fetch.call(wrapper.vm);
+ expect(wrapper.vm.version).toBe('1.2.3');
+ });
+
+ it('should set version to latest for upgrade action', async() => {
+ const plugin = { installableVersions: [{ version: '1.1.0' }, { version: '1.0.0' }] };
+
+ wrapper = mountComponent({ plugin, action: 'upgrade' });
+ await wrapper.vm.$options.fetch.call(wrapper.vm);
+ expect(wrapper.vm.version).toBe('1.1.0');
+ });
+
+ it('should set version to next oldest for downgrade action', async() => {
+ const plugin = {
+ installed: true,
+ installedVersion: '1.1.0',
+ installableVersions: [{ version: '1.1.0' }, { version: '1.0.0' }]
+ };
+
+ wrapper = mountComponent({ plugin, action: 'downgrade' });
+ await wrapper.vm.$options.fetch.call(wrapper.vm);
+ expect(wrapper.vm.version).toBe('1.0.0');
+ });
+ });
+
+ describe('versionOptions', () => {
+ it('should include and disable the current version', () => {
+ const plugin = {
+ installableVersions: [
+ { version: '1.1.0' },
+ { version: '1.0.0' },
+ ]
+ };
+
+ wrapper = mountComponent({ plugin });
+ wrapper.vm.currentVersion = '1.0.0';
+
+ const options = wrapper.vm.versionOptions;
+ const currentOption = options.find((o: any) => o.value === '1.0.0');
+
+ expect(currentOption).toBeDefined();
+ expect(currentOption.disabled).toBe(true);
+ expect(currentOption.label).toContain('(plugins.labels.current)');
+ });
+ });
+
+ describe('buttonMode', () => {
+ beforeEach(() => {
+ wrapper = mountComponent({ action: 'upgrade' });
+ wrapper.vm.currentVersion = '1.0.0';
+ });
+
+ it('should be "upgrade" if selected version is higher', async() => {
+ wrapper.vm.version = '1.1.0';
+ await wrapper.vm.$nextTick();
+ expect(wrapper.vm.buttonMode).toBe('upgrade');
+ });
+
+ it('should be "downgrade" if selected version is lower', async() => {
+ wrapper.vm.version = '0.9.0';
+ await wrapper.vm.$nextTick();
+ expect(wrapper.vm.buttonMode).toBe('downgrade');
+ });
+ });
+});
diff --git a/shell/edit/auth/oidc.vue b/shell/edit/auth/oidc.vue
index 7dd4318850..9826f4cd45 100644
--- a/shell/edit/auth/oidc.vue
+++ b/shell/edit/auth/oidc.vue
@@ -59,11 +59,16 @@ export default {
userInfoEndpoint: null,
},
// TODO #13457: this is duplicated due wrong format
- oidcScope: [],
- SLO_OPTION_VALUES
+ oidcScope: [],
+ SLO_OPTION_VALUES,
+ addCustomClaims: false,
};
},
+ created() {
+ this.registerBeforeHook(this.willSave, 'willSave');
+ },
+
computed: {
tArgs() {
return {
@@ -140,6 +145,10 @@ export default {
return this.model?.id === 'cognito';
},
+ isGenericOidc() {
+ return this.model?.id === 'genericoidc';
+ },
+
isLogoutAllSupported() {
return this.model?.logoutAllSupported;
},
@@ -220,6 +229,15 @@ export default {
this.model.logoutAllForced = false;
break;
}
+ },
+
+ model: {
+ handler(newVal) {
+ if (newVal?.nameClaim || newVal?.groupsClaim || newVal?.emailClaim) {
+ this.addCustomClaims = true;
+ }
+ },
+ once: true
}
},
@@ -248,6 +266,14 @@ export default {
updateScope() {
this.model.scope = this.oidcScope.join(' ');
+ },
+
+ willSave() {
+ if (this.isGenericOidc && !this.addCustomClaims) {
+ this.model.nameClaim = undefined;
+ this.model.groupsClaim = undefined;
+ this.model.emailClaim = undefined;
+ }
}
}
};
@@ -390,21 +416,60 @@ export default {
-
+
+
+
+ {{ t('authConfig.oidc.customClaims.label') }}
+
+
+
@@ -608,4 +673,9 @@ export default {
margin: 0 3px;
}
}
+
+ .checkbox-flex {
+ display: flex;
+ flex-direction: column;
+ }
diff --git a/shell/mixins/__tests__/chart.test.ts b/shell/mixins/__tests__/chart.test.ts
index ace87cce70..009ec7d02e 100644
--- a/shell/mixins/__tests__/chart.test.ts
+++ b/shell/mixins/__tests__/chart.test.ts
@@ -213,7 +213,7 @@ describe('chartMixin', () => {
});
expect(wrapper.vm.action).toStrictEqual({
- name: 'upgradeVersion',
+ name: 'upgrade',
tKey: 'upgrade',
icon: 'icon-upgrade-alt',
});
diff --git a/shell/mixins/chart.js b/shell/mixins/chart.js
index fbef5bb3eb..18e6afc416 100644
--- a/shell/mixins/chart.js
+++ b/shell/mixins/chart.js
@@ -242,7 +242,7 @@ export default {
if (compare(this.currentVersion, this.targetVersion) < 0) {
return {
- name: 'upgradeVersion', tKey: 'upgrade', icon: 'icon-upgrade-alt'
+ name: 'upgrade', tKey: 'upgrade', icon: 'icon-upgrade-alt'
};
}
diff --git a/shell/models/provisioning.cattle.io.cluster.js b/shell/models/provisioning.cattle.io.cluster.js
index dc2ca516b1..0211e38838 100644
--- a/shell/models/provisioning.cattle.io.cluster.js
+++ b/shell/models/provisioning.cattle.io.cluster.js
@@ -391,6 +391,15 @@ export default class ProvCluster extends SteveModel {
const pCluster = this.$rootGetters['management/byId'](CAPI.RANCHER_CLUSTER, this.id);
const name = this.status?.clusterName || pCluster?.status?.clusterName;
+ try {
+ if (name) {
+ // Just in case we're not generically watching all mgmt clusters and...
+ // thus won't receive new mgmt cluster over socket...
+ // fire and forget a request to fetch it (this won't make multiple requests if one is already running)
+ this.$dispatch('find', { type: MANAGEMENT.CLUSTER, id: name });
+ }
+ } catch {}
+
return name && !!this.$rootGetters['management/byId'](MANAGEMENT.CLUSTER, name);
}, this.$rootGetters['i18n/t']('cluster.managementTimeout'), timeout, interval);
}
diff --git a/shell/package.json b/shell/package.json
index 57931aea00..5936b33344 100644
--- a/shell/package.json
+++ b/shell/package.json
@@ -1,6 +1,6 @@
{
"name": "@rancher/shell",
- "version": "3.0.5",
+ "version": "3.0.6",
"description": "Rancher Dashboard Shell",
"repository": "https://github.com/rancherlabs/dashboard",
"license": "Apache-2.0",
diff --git a/shell/pages/c/_cluster/uiplugins/PluginInfoPanel.vue b/shell/pages/c/_cluster/uiplugins/PluginInfoPanel.vue
index d256f0cb0c..3364a5e5ff 100644
--- a/shell/pages/c/_cluster/uiplugins/PluginInfoPanel.vue
+++ b/shell/pages/c/_cluster/uiplugins/PluginInfoPanel.vue
@@ -1,14 +1,18 @@