diff --git a/docusaurus/docs/extensions/advanced/version-compatibility.md b/docusaurus/docs/extensions/advanced/version-compatibility.md
index 4761bd9bcbe..15247216f22 100644
--- a/docusaurus/docs/extensions/advanced/version-compatibility.md
+++ b/docusaurus/docs/extensions/advanced/version-compatibility.md
@@ -11,9 +11,13 @@ Here are the annotations you can modify:
| --- | --- | --- |
| `catalog.cattle.io/kube-version` | v2.7.0 | Defines a possible minimum and maximum Kubernetes version for the extension to work with. Prevents extension version from being loaded on the UI
| `catalog.cattle.io/rancher-version` | v2.7.0 | Defines a possible minimum and maximum Rancher version for the extension to work with. Prevents extension version from being loaded on the UI
+| `catalog.cattle.io/host` | v2.7.0 | Defines the host for the extension, which should have the value `rancher-manager`. Prevents extension version from being loaded on the UI
+| `catalog.cattle.io/ui-extensions-version` | v2.9.0 | Defines a possible minimum and maximum Extensions API version for the extension to work with. Prevents extension version from being loaded on the UI
| `catalog.cattle.io/ui-version` | v2.7.3 | Defines a possible minimum and maximum Rancher Dashboard version for the extension to work with. Extension version will be loaded but will appear as disabled
-
-Since both `catalog.cattle.io/kube-version` and `catalog.cattle.io/rancher-version` will prevent a given extension version from being loaded onto the UI by the extensions operator, `catalog.cattle.io/ui-version` will have a sligthly different behaviour and allow for the extension version to be loaded, but will disable it on the Install, Upgrade and Rollback scenarios, where that given version will not appear on those dropdowns and also the extension version button on the side panel will be disabled and will show a tooltip on hover with the information, such as:
+
+**NOTE: The annotation `catalog.cattle.io/ui-extensions-version` will become mandatory from Rancher 2.10 and onwards. If the annotation is not present on a given extension Helm Chart, the extension itself will not be loaded**
+
+All annotations will prevent the loading of an extension into Rancher apart from `catalog.cattle.io/ui-version`, which will have a sligthly different behaviour and allow for the extension version to be loaded, but will disable it on the Install, Upgrade and Rollback scenarios, where that given version will not appear on those dropdowns and also the extension version button on the side panel will be disabled and will show a tooltip on hover with the information, such as:
![UI version annotation](../screenshots/ui-version-annotation.png)
\ No newline at end of file
diff --git a/docusaurus/docs/extensions/support-matrix.md b/docusaurus/docs/extensions/support-matrix.md
index 711f28be254..dc900df2b65 100644
--- a/docusaurus/docs/extensions/support-matrix.md
+++ b/docusaurus/docs/extensions/support-matrix.md
@@ -5,11 +5,12 @@
The Shell package enables Extensions to integrate with Rancher.
It's important to know which version of the Shell package is compatible with each Rancher version:
-| | Rancher 2.7.x | Rancher 2.8.x | Rancher 2.9.x |
-|---|---|---|---|
-|Shell **0.3.8**|Supported|Limited support|Not supported|
-|Shell 0.5.3/**1.2.3**|Limited support|Supported|Not supported|
-|Shell **2.0.1**|Not supported|Not supported|Supported|
+| | Rancher 2.7.x | Rancher 2.8.x
(Extensions API V1) | Rancher 2.9.x
(Extensions API V2) | Rancher 2.10.x
(Extensions API V3) |
+|---|---|---|---|---|
+|Shell **0.3.8**|Supported|Limited support|Not supported|Not supported|
+|Shell 0.5.3/**1.2.3**|Limited support|Supported|Not supported|Not supported|
+|Shell **2.0.1**|Not supported|Not supported|Supported|Not supported|
+|Shell **3.0.0**|Not supported|Not supported|Not supported|Supported|
To know more about the Shell package versioning take a look at the diagram [here](./rancher-2.9-support).
diff --git a/shell/assets/translations/en-us.yaml b/shell/assets/translations/en-us.yaml
index 40b24a7589d..7f9f355fd83 100644
--- a/shell/assets/translations/en-us.yaml
+++ b/shell/assets/translations/en-us.yaml
@@ -4267,6 +4267,7 @@ inactivity:
plugins:
incompatibleRancherVersion: "The latest version of this extension ({ version }) is not compatible with the current Rancher version ({ required })."
incompatibleKubeVersion: "The latest version of this extension ({ version }) is not compatible with the current Kube version ({ required })."
+ incompatibleUiExtensionsApiVersionMissing: 'The latest version of this extension ({ version }) is missing the mandatory annotation catalog.cattle.io/ui-extensions-version from Rancher 2.10 and onwards.'
incompatibleUiExtensionsApiVersion: "The latest version of this extension ({ version }) is not compatible with the current Extensions API version ({ required })."
incompatibleHost: 'The latest version of this extension ({ version }) has a host of "{ required }" which is not compatible with this application "{ mainHost }".'
currentInstalledVersionBlockedByKubeVersion: "This version is not compatible with the current Kubernetes version ({ kubeVersion } Vs { kubeVersionToCheck })."
@@ -4286,9 +4287,11 @@ plugins:
title: Error loading extension
message: Could not load extension code
generic: Extension error
- api: This Extension is not compatible with the current Extensions API version
- host: This Extension is not compatible with this application
- version: This Extension is not compatible with this version of Rancher
+ apiAnnotationMissing: 'Unable to load Extension. The version installed is not compatible with the current Extensions API Version (Extension is missing the annotation catalog.cattle.io/ui-extensions-version which implies incompatibility with Rancher 2.10 and onwards)'
+ api: Unable to load Extension. The version installed is not compatible with the current Extensions API version
+ host: Unable to load Extension. The version installed is not compatible with this application host
+ version: Unable to load Extension. The version installed is not compatible with the current version of Rancher
+ kubeVersion: Unable to load Extension. The version installed is not compatible with the current Rancher kubernetes version
load: An error occurred loading the code for this Extension
developerPkg: This Extension has been loaded internally, so we won't load the external version
success:
@@ -4308,6 +4311,7 @@ plugins:
versionError: Could not load version information
requiresRancherVersion: "Requires Rancher {required}"
requiresKubeVersion: "Requires Kube version {required}"
+ requiresExtensionApiVersionMissing: 'Missing the annotation catalog.cattle.io/ui-extensions-version which implies incompatibility with Rancher 2.10 and onwards'
requiresExtensionApiVersion: "Requires Extensions API version {required}"
requiresHost: 'Requires a host that matches "{mainHost}"'
empty:
diff --git a/shell/config/uiplugins.js b/shell/config/uiplugins.js
index 10c724faa1c..6d6193dfd34 100644
--- a/shell/config/uiplugins.js
+++ b/shell/config/uiplugins.js
@@ -3,44 +3,36 @@ import semver from 'semver';
// Version of the plugin API supported
// here we inject the current shell version that we read in vue.config
export const UI_EXTENSIONS_API_VERSION = process.env.UI_EXTENSIONS_API_VERSION;
+
export const UI_PLUGIN_HOST_APP = 'rancher-manager';
export const UI_PLUGIN_BASE_URL = '/v1/uiplugins';
-
export const UI_PLUGIN_NAMESPACE = 'cattle-ui-plugin-system';
// Annotation name and value that indicate a chart is a UI plugin
-export const UI_PLUGIN_ANNOTATION_NAME = 'catalog.cattle.io/ui-component';
-export const UI_PLUGIN_ANNOTATION_VALUE = 'plugins';
-
-export const UI_PLUGIN_OPERATOR_CRD_CHART_NAME = 'ui-plugin-operator-crd';
-export const UI_PLUGIN_OPERATOR_CHART_NAME = 'ui-plugin-operator';
-
-export const UI_PLUGIN_CHARTS = [
- UI_PLUGIN_OPERATOR_CHART_NAME,
- UI_PLUGIN_OPERATOR_CRD_CHART_NAME,
-];
-
-// Expected chart repo name for the UI Plugins operator
-export const UI_PLUGIN_OPERATOR_REPO_NAME = 'rancher-charts';
-
-// Info for the Helm Chart Repository that we will add
-export const UI_PLUGINS_REPO_NAME = 'rancher-ui-plugins';
-
-export const UI_PLUGINS_REPO_URL = 'https://github.com/rancher/ui-plugin-charts';
-export const UI_PLUGINS_REPO_BRANCH = 'main';
-
-// Info for the Helm Chart Repo for Partner Extensions
-export const UI_PLUGINS_PARTNERS_REPO_NAME = 'partner-extensions';
-
-export const UI_PLUGINS_PARTNERS_REPO_URL = 'https://github.com/rancher/partner-extensions';
-export const UI_PLUGINS_PARTNERS_REPO_BRANCH = 'main';
-
-// Info for the Helm Chart Repo for Community Extensions
-export const UI_PLUGINS_COMMUNITY_REPO_NAME = 'community-extensions';
+export const UI_PLUGIN_ANNOTATION = {
+ NAME: 'catalog.cattle.io/ui-component',
+ VALUE: 'plugins',
+};
-export const UI_PLUGINS_COMMUNITY_REPO_URL = 'https://github.com/rancher/community-extensions';
-export const UI_PLUGINS_COMMUNITY_REPO_BRANCH = 'main';
+// Info for the Helm Chart Repositories
+export const UI_PLUGINS_REPOS = {
+ OFFICIAL: {
+ NAME: 'rancher-ui-plugins',
+ URL: 'https://github.com/rancher/ui-plugin-charts',
+ BRANCH: 'main',
+ },
+ PARTNERS: {
+ NAME: 'partner-extensions',
+ URL: 'https://github.com/rancher/partner-extensions',
+ BRANCH: 'main',
+ },
+ COMMUNITY: {
+ NAME: 'community-extensions',
+ URL: 'https://github.com/rancher/community-extensions',
+ BRANCH: 'main',
+ },
+};
// Chart annotations
export const UI_PLUGIN_CHART_ANNOTATIONS = {
@@ -57,22 +49,15 @@ export const UI_PLUGIN_CHART_ANNOTATIONS = {
export const UI_PLUGIN_LABELS = {
CATALOG_IMAGE: 'catalog.cattle.io/ui-extensions-catalog-image',
REPOSITORY: 'catalog.cattle.io/ui-extensions-repository',
- CATALOG: 'catalog.cattle.io/ui-extensions-catalog'
-};
-
-// Plugin Metadata properties
-export const UI_PLUGIN_METADATA = {
- RANCHER_VERSION: 'rancherVersion',
- EXTENSION_VERSION: 'extVersion',
- EXTENSIONS_HOST: 'host',
- DISPLAY_NAME: 'displayName',
+ CATALOG: 'catalog.cattle.io/ui-extensions-catalog',
};
export const EXTENSIONS_INCOMPATIBILITY_TYPES = {
- UI: 'uiVersion',
- EXTENSIONS_API: 'extensionsApiVersion',
- KUBE: 'kubeVersion',
- HOST: 'host'
+ UI: 'uiVersion',
+ EXTENSIONS_API_MISSING: 'extensionsApiVersionMissing',
+ EXTENSIONS_API: 'extensionsApiVersion',
+ KUBE: 'kubeVersion',
+ HOST: 'host',
};
export const EXTENSIONS_INCOMPATIBILITY_DATA = {
@@ -80,74 +65,89 @@ export const EXTENSIONS_INCOMPATIBILITY_DATA = {
type: EXTENSIONS_INCOMPATIBILITY_TYPES.UI,
cardMessageKey: 'plugins.incompatibleRancherVersion',
tooltipKey: 'plugins.info.requiresRancherVersion',
- mainHost: UI_PLUGIN_HOST_APP
+ },
+ EXTENSIONS_API_MISSING: {
+ type: EXTENSIONS_INCOMPATIBILITY_TYPES.EXTENSIONS_API_MISSING,
+ cardMessageKey: 'plugins.incompatibleUiExtensionsApiVersionMissing',
+ tooltipKey: 'plugins.info.requiresExtensionApiVersionMissing',
},
EXTENSIONS_API: {
type: EXTENSIONS_INCOMPATIBILITY_TYPES.EXTENSIONS_API,
cardMessageKey: 'plugins.incompatibleUiExtensionsApiVersion',
tooltipKey: 'plugins.info.requiresExtensionApiVersion',
- mainHost: UI_PLUGIN_HOST_APP
},
KUBE: {
type: EXTENSIONS_INCOMPATIBILITY_TYPES.KUBE,
cardMessageKey: 'plugins.incompatibleKubeVersion',
tooltipKey: 'plugins.info.requiresKubeVersion',
- mainHost: UI_PLUGIN_HOST_APP
},
HOST: {
type: EXTENSIONS_INCOMPATIBILITY_TYPES.HOST,
cardMessageKey: 'plugins.incompatibleHost',
tooltipKey: 'plugins.info.requiresHost',
- mainHost: UI_PLUGIN_HOST_APP
- }
+ mainHost: UI_PLUGIN_HOST_APP,
+ },
};
export function isUIPlugin(chart) {
- return !!chart?.versions.find((v) => {
- return v.annotations && v.annotations[UI_PLUGIN_ANNOTATION_NAME] === UI_PLUGIN_ANNOTATION_VALUE;
- });
+ return !!chart?.versions.find((v) => v.annotations?.[UI_PLUGIN_ANNOTATION.NAME] === UI_PLUGIN_ANNOTATION.VALUE);
}
export function uiPluginHasAnnotation(chart, name, value) {
- return !!chart?.versions.find((v) => {
- return v.annotations && v.annotations[name] === value;
- });
+ return !!chart?.versions.find((v) => v.annotations?.[name] === value);
}
/**
- * Get value of the annotation from teh latest version for a chart
+ * Get value of the annotation from the latest version for a chart
*/
export function uiPluginAnnotation(chart, name) {
- if (chart?.versions?.length > 0) {
- return chart.versions[0].annotations?.[name];
- }
-
- return undefined;
+ return chart?.versions?.[0]?.annotations?.[name];
}
/**
- * Parse the rancher version string
+ * Parse the Rancher version string
*/
function parseRancherVersion(v) {
- let parsedRancherVersion = semver.coerce(v)?.version;
- const splitArr = parsedRancherVersion.split('.');
+ let parsedVersion = semver.coerce(v)?.version;
+ const splitArr = parsedVersion?.split('.');
// this is a scenario where we are on a "head" version of some sort... we can't infer the patch version from it
// so we apply a big patch version number to make sure we follow through with the minor
if (v.includes('-') && splitArr?.length === 3) {
- parsedRancherVersion = `${ splitArr[0] }.${ splitArr[1] }.999`;
+ parsedVersion = `${ splitArr[0] }.${ splitArr[1] }.999`;
}
- return parsedRancherVersion;
+ return parsedVersion;
}
-// i18n-uses plugins.error.generic, plugins.error.api, plugins.error.host
+/**
+ * Check if a version is incompatible with the current environment
+ */
+function checkIncompatibility(currentVersion, requiredVersion, incompatibilityData, returnObj, versionObj) {
+ if ((incompatibilityData.type === EXTENSIONS_INCOMPATIBILITY_TYPES.EXTENSIONS_API_MISSING && !requiredVersion) || (requiredVersion && !semver.satisfies(currentVersion, requiredVersion))) {
+ if (!returnObj) {
+ return false;
+ }
+ versionObj.isVersionCompatible = false;
+ versionObj.versionIncompatibilityData = { ...incompatibilityData, required: requiredVersion };
+
+ return versionObj;
+ }
+
+ return true;
+}
+
+// i18n-uses plugins.error.generic, plugins.error.api, plugins.error.host, plugins.error.kubeVersion, plugins.error.version, plugins.error.developerPkg, plugins.error.apiAnnotationMissing
/**
* Whether an extension should be loaded based on the metadata returned by the backend in the UIPlugins resource instance
- * @returns String || Boolean
+ * The output will be used to PREVENT loading of an extension that is already installed but isn't compatible with the system
+ *
+ * String output will display a message on the extension card to notify users on why the extension was not loaded
+ *
+ * @returns String | Boolean
*/
-export function shouldNotLoadPlugin(UIPluginResource, rancherVersion, loadedPlugins) {
+export function shouldNotLoadPlugin(UIPluginResource, { rancherVersion, kubeVersion }, loadedPlugins) {
if (!UIPluginResource.name || !UIPluginResource.version || !UIPluginResource.endpoint) {
return 'plugins.error.generic';
}
@@ -155,25 +155,37 @@ export function shouldNotLoadPlugin(UIPluginResource, rancherVersion, loadedPlug
// Extension chart specified a required extension API version
// we are propagating the annotations in pkg/package.json for any extension
// inside the "spec.plugin.metadata" property of UIPlugin resource
- const requiredUiExtensionsVersion = UIPluginResource.spec?.plugin?.metadata?.[UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_VERSION];
+ const requiredUiExtensionsVersion = UIPluginResource.metadata?.[UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_VERSION];
// semver.coerce will get rid of any suffix on the version numbering (-rc, -head, etc)
- const parsedUiExtensionsApiVersion = semver.coerce(UI_EXTENSIONS_API_VERSION)?.version || UI_EXTENSIONS_API_VERSION;
+ const parsedUiExtensionsApiVersion = semver.coerce(UI_EXTENSIONS_API_VERSION)?.version;
const parsedRancherVersion = rancherVersion ? parseRancherVersion(rancherVersion) : '';
+ const parsedKubeVersion = kubeVersion ? semver.coerce(kubeVersion)?.version : '';
- if (requiredUiExtensionsVersion && !semver.satisfies(parsedUiExtensionsApiVersion, requiredUiExtensionsVersion)) {
+ if (!requiredUiExtensionsVersion) {
+ return 'plugins.error.apiAnnotationMissing';
+ } else if (requiredUiExtensionsVersion && !semver.satisfies(parsedUiExtensionsApiVersion, requiredUiExtensionsVersion)) {
return 'plugins.error.api';
}
// Host application
- const requiredHost = UIPluginResource.metadata?.[UI_PLUGIN_METADATA.EXTENSIONS_HOST];
+ const requiredHost = UIPluginResource.metadata?.[UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_HOST];
if (requiredHost && requiredHost !== UI_PLUGIN_HOST_APP) {
return 'plugins.error.host';
}
+ // Kube version
+ if (parsedKubeVersion) {
+ const requiredKubeVersion = UIPluginResource.metadata?.[UI_PLUGIN_CHART_ANNOTATIONS.KUBE_VERSION];
+
+ if (requiredKubeVersion && !semver.satisfies(parsedKubeVersion, requiredKubeVersion)) {
+ return 'plugins.error.kubeVersion';
+ }
+ }
+
// Rancher version
if (parsedRancherVersion) {
- const requiredRancherVersion = UIPluginResource.metadata?.[UI_PLUGIN_METADATA.RANCHER_VERSION];
+ const requiredRancherVersion = UIPluginResource.metadata?.[UI_PLUGIN_CHART_ANNOTATIONS.RANCHER_VERSION];
if (requiredRancherVersion && !semver.satisfies(parsedRancherVersion, requiredRancherVersion)) {
return 'plugins.error.version';
@@ -197,104 +209,62 @@ export function shouldNotLoadPlugin(UIPluginResource, rancherVersion, loadedPlug
/**
* Wether an extension version is available to be installed, based on the annotations present in the Helm chart version
* backend may not automatically "limit" a particular version but dashboard will disable that version for install with this check
- * @returns Boolean || Object
+ *
+ * The output will be used to display a message on the extension card to notify users if a LATEST version of an extension is available but isn't compatible (cardMessageKey)
+ * The output will also disable the buttons in the slide-in panel with extension details, displaying a tooltip message with the reason (tooltipKey)
+ *
+ * @returns Boolean | Object
*/
export function isSupportedChartVersion(versionData, returnObj = false) {
const { version, rancherVersion, kubeVersion } = versionData;
-
- // semver.coerce will get rid of any suffix on the version numbering (-rc, -head, etc)
+ const versionObj = {
+ ...version, isVersionCompatible: true, versionIncompatibilityData: {}
+ };
const parsedRancherVersion = rancherVersion ? parseRancherVersion(rancherVersion) : '';
- const requiredUiVersion = version.annotations?.[UI_PLUGIN_CHART_ANNOTATIONS.UI_VERSION];
- const requiredKubeVersion = version.annotations?.[UI_PLUGIN_CHART_ANNOTATIONS.KUBE_VERSION];
- const versionObj = { ...version };
-
- // reset compatibility property
- versionObj.isVersionCompatible = true;
- versionObj.versionIncompatibilityData = {};
-
- // check "catalog.cattle.io/kube-version" annotation
- // we keep it as first check since there is a card notification to be displayed
- // in case an extension version installed has an incompatibility with the kube version and is not loaded
- if (kubeVersion && requiredKubeVersion && !semver.satisfies(kubeVersion, requiredKubeVersion)) {
- if (!returnObj) {
- return false;
+ const parsedUiExtensionsApiVersion = semver.coerce(UI_EXTENSIONS_API_VERSION)?.version;
+
+ const checks = [
+ {
+ currentVersion: kubeVersion,
+ requiredVersion: version.annotations?.[UI_PLUGIN_CHART_ANNOTATIONS.KUBE_VERSION],
+ incompatibilityData: EXTENSIONS_INCOMPATIBILITY_DATA.KUBE,
+ },
+ {
+ currentVersion: parsedRancherVersion,
+ requiredVersion: version.annotations?.[UI_PLUGIN_CHART_ANNOTATIONS.RANCHER_VERSION],
+ incompatibilityData: EXTENSIONS_INCOMPATIBILITY_DATA.UI,
+ },
+ {
+ currentVersion: parsedRancherVersion,
+ requiredVersion: version.annotations?.[UI_PLUGIN_CHART_ANNOTATIONS.UI_VERSION],
+ incompatibilityData: EXTENSIONS_INCOMPATIBILITY_DATA.UI,
+ },
+ {
+ currentVersion: parsedUiExtensionsApiVersion,
+ requiredVersion: version.annotations?.[UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_VERSION],
+ incompatibilityData: EXTENSIONS_INCOMPATIBILITY_DATA.EXTENSIONS_API_MISSING,
+ },
+ {
+ currentVersion: parsedUiExtensionsApiVersion,
+ requiredVersion: version.annotations?.[UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_VERSION],
+ incompatibilityData: EXTENSIONS_INCOMPATIBILITY_DATA.EXTENSIONS_API,
+ },
+ {
+ currentVersion: UI_PLUGIN_HOST_APP,
+ requiredVersion: version.annotations?.[UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_HOST],
+ incompatibilityData: EXTENSIONS_INCOMPATIBILITY_DATA.HOST,
+ },
+ ];
+
+ for (const { currentVersion, requiredVersion, incompatibilityData } of checks) {
+ const result = checkIncompatibility(currentVersion, requiredVersion, incompatibilityData, returnObj, versionObj);
+
+ if (result !== true) {
+ return result;
}
-
- versionObj.isVersionCompatible = false;
- versionObj.versionIncompatibilityData = Object.assign({}, EXTENSIONS_INCOMPATIBILITY_DATA.KUBE);
- versionObj.versionIncompatibilityData.required = requiredKubeVersion;
-
- return versionObj;
- }
-
- // we aren't on a "published" version of Rancher and therefore in a "-head" or similar
- // Backend will NOT block an extension version from being available IF we are on HEAD versions!!
- // we need to enforce that check if we are on a HEAD world
- if (rancherVersion && rancherVersion.includes('-')) {
- const requiredRancherVersion = version.annotations?.[UI_PLUGIN_CHART_ANNOTATIONS.RANCHER_VERSION];
-
- if (parsedRancherVersion && !semver.satisfies(parsedRancherVersion, requiredRancherVersion)) {
- if (!returnObj) {
- return false;
- }
-
- versionObj.isVersionCompatible = false;
- versionObj.versionIncompatibilityData = Object.assign({}, EXTENSIONS_INCOMPATIBILITY_DATA.UI);
- versionObj.versionIncompatibilityData.required = requiredRancherVersion;
-
- return versionObj;
- }
- }
-
- // check host application
- const requiredHost = version.annotations?.[UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_HOST];
-
- if (requiredHost && requiredHost !== UI_PLUGIN_HOST_APP) {
- if (!returnObj) {
- return false;
- }
-
- versionObj.isVersionCompatible = false;
- versionObj.versionIncompatibilityData = Object.assign({}, EXTENSIONS_INCOMPATIBILITY_DATA.HOST);
- versionObj.versionIncompatibilityData.required = requiredHost;
-
- return versionObj;
}
- // check "catalog.cattle.io/ui-extensions-version" annotation
- const requiredUiExtensionsApiVersion = version.annotations?.[UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_VERSION];
- const parsedUiExtensionsApiVersion = semver.coerce(UI_EXTENSIONS_API_VERSION)?.version || UI_EXTENSIONS_API_VERSION;
-
- if (requiredUiExtensionsApiVersion && parsedUiExtensionsApiVersion && !semver.satisfies(parsedUiExtensionsApiVersion, requiredUiExtensionsApiVersion)) {
- if (!returnObj) {
- return false;
- }
-
- versionObj.isVersionCompatible = false;
- versionObj.versionIncompatibilityData = Object.assign({}, EXTENSIONS_INCOMPATIBILITY_DATA.EXTENSIONS_API);
- versionObj.versionIncompatibilityData.required = requiredUiExtensionsApiVersion;
-
- return versionObj;
- }
-
- // check "catalog.cattle.io/ui-version" annotation
- if (requiredUiVersion && parsedRancherVersion && !semver.satisfies(parsedRancherVersion, requiredUiVersion)) {
- if (!returnObj) {
- return false;
- }
-
- versionObj.isVersionCompatible = false;
- versionObj.versionIncompatibilityData = Object.assign({}, EXTENSIONS_INCOMPATIBILITY_DATA.UI);
- versionObj.versionIncompatibilityData.required = requiredUiVersion;
-
- return versionObj;
- }
-
- if (returnObj) {
- return versionObj;
- }
-
- return true;
+ return returnObj ? versionObj : true;
}
export function isChartVersionHigher(versionA, versionB) {
diff --git a/shell/config/version.js b/shell/config/version.js
index 15c286cdc53..abbf8856b06 100644
--- a/shell/config/version.js
+++ b/shell/config/version.js
@@ -2,6 +2,7 @@
* Store version data retrieved from the backend /rancherversion API
*/
let _versionData = { RancherPrime: 'false' };
+let _kubeVersionData = {};
export function isRancherPrime() {
return _versionData.RancherPrime?.toLowerCase() === 'true';
@@ -15,3 +16,12 @@ export function setVersionData(v) {
// Remove any properties on 'v' we don't want
_versionData = JSON.parse(JSON.stringify(v));
}
+
+export function getKubeVersionData() {
+ return _kubeVersionData;
+}
+
+export function setKubeVersionData(v) {
+ // Remove any properties on 'v' we don't want
+ _kubeVersionData = JSON.parse(JSON.stringify(v));
+}
diff --git a/shell/initialize/install-plugins.js b/shell/initialize/install-plugins.js
index 69a11ad4f41..45dfb9508c4 100644
--- a/shell/initialize/install-plugins.js
+++ b/shell/initialize/install-plugins.js
@@ -25,7 +25,6 @@ import plugins from '@shell/core/plugins.js';
import pluginsLoader from '@shell/core/plugins-loader.js';
import replaceAll from '@shell/plugins/replaceall';
import steveCreateWorker from '@shell/plugins/steve-create-worker';
-import version from '@shell/plugins/version';
import emberCookie from '@shell/plugins/ember-cookie';
import ShortKey from '@shell/plugins/shortkey';
@@ -43,7 +42,7 @@ export async function installPlugins(vueApp) {
}
export async function installInjectedPlugins(app, vueApp) {
- const pluginDefinitions = [config, cookieUniversal, axios, plugins, pluginsLoader, axiosShell, intNumber, codeMirror, nuxtClientInit, replaceAll, backButton, plugin, version, steveCreateWorker, emberCookie];
+ const pluginDefinitions = [config, cookieUniversal, axios, plugins, pluginsLoader, axiosShell, intNumber, codeMirror, nuxtClientInit, replaceAll, backButton, plugin, steveCreateWorker, emberCookie];
const installations = pluginDefinitions.map(async(pluginDefinition) => {
if (typeof pluginDefinition === 'function') {
diff --git a/shell/mixins/resource-manager.js b/shell/mixins/resource-manager.js
index c249eff812f..d38b16160f5 100644
--- a/shell/mixins/resource-manager.js
+++ b/shell/mixins/resource-manager.js
@@ -55,7 +55,7 @@ export default {
const type = types[i];
const status = hash[type].status;
// if it's namespaced, we get the data on 'items' prop, for non-namespaced it's 'data' prop...
- const requestData = hash[type].value.items || hash[type].value.data || hash[type].value;
+ const requestData = hash[type]?.value?.items || hash[type]?.value?.data || hash[type]?.value;
if (status === 'fulfilled' && resourceData.data[type] && resourceData.data[type].applyTo?.length) {
for (let y = 0; y < resourceData.data[type].applyTo.length; y++) {
diff --git a/shell/pages/c/_cluster/uiplugins/AddExtensionRepos.vue b/shell/pages/c/_cluster/uiplugins/AddExtensionRepos.vue
index d0b45848392..5b1f190cfdf 100644
--- a/shell/pages/c/_cluster/uiplugins/AddExtensionRepos.vue
+++ b/shell/pages/c/_cluster/uiplugins/AddExtensionRepos.vue
@@ -2,14 +2,7 @@
import { CATALOG } from '@shell/config/types';
import Dialog from '@shell/components/Dialog.vue';
import Checkbox from '@components/Form/Checkbox/Checkbox.vue';
-import {
- UI_PLUGINS_REPO_NAME,
- UI_PLUGINS_REPO_URL,
- UI_PLUGINS_REPO_BRANCH,
- UI_PLUGINS_PARTNERS_REPO_NAME,
- UI_PLUGINS_PARTNERS_REPO_URL,
- UI_PLUGINS_PARTNERS_REPO_BRANCH,
-} from '@shell/config/uiplugins';
+import { UI_PLUGINS_REPOS } from '@shell/config/uiplugins';
import { isRancherPrime } from '@shell/config/version';
export default {
@@ -38,15 +31,15 @@ export default {
reposInfo: {
official: {
repo: undefined,
- name: UI_PLUGINS_REPO_NAME,
- url: UI_PLUGINS_REPO_URL,
- branch: UI_PLUGINS_REPO_BRANCH,
+ name: UI_PLUGINS_REPOS.OFFICIAL.NAME,
+ url: UI_PLUGINS_REPOS.OFFICIAL.URL,
+ branch: UI_PLUGINS_REPOS.OFFICIAL.BRANCH,
},
partners: {
repo: undefined,
- name: UI_PLUGINS_PARTNERS_REPO_NAME,
- url: UI_PLUGINS_PARTNERS_REPO_URL,
- branch: UI_PLUGINS_PARTNERS_REPO_BRANCH,
+ name: UI_PLUGINS_REPOS.PARTNERS.NAME,
+ url: UI_PLUGINS_REPOS.PARTNERS.URL,
+ branch: UI_PLUGINS_REPOS.PARTNERS.BRANCH,
}
},
isDialogActive: false,
@@ -55,10 +48,10 @@ export default {
computed: {
hasRancherUIPluginsRepo() {
- return !!this.repos.find((r) => r.urlDisplay === UI_PLUGINS_REPO_URL);
+ return !!this.repos.find((r) => r.urlDisplay === UI_PLUGINS_REPOS.OFFICIAL.URL);
},
hasRancherUIPartnersPluginsRepo() {
- return !!this.repos.find((r) => r.urlDisplay === UI_PLUGINS_PARTNERS_REPO_URL);
+ return !!this.repos.find((r) => r.urlDisplay === UI_PLUGINS_REPOS.PARTNERS.URL);
}
},
diff --git a/shell/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue b/shell/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue
index 2c14af25e56..59ae943c1d4 100644
--- a/shell/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue
+++ b/shell/pages/c/_cluster/uiplugins/DeveloperInstallDialog.vue
@@ -4,7 +4,7 @@ import AppModal from '@shell/components/AppModal.vue';
import { LabeledInput } from '@components/Form/LabeledInput';
import Checkbox from '@components/Form/Checkbox/Checkbox.vue';
import { UI_PLUGIN } from '@shell/config/types';
-import { UI_PLUGIN_NAMESPACE } from '@shell/config/uiplugins';
+import { UI_PLUGIN_CHART_ANNOTATIONS, UI_PLUGIN_NAMESPACE } from '@shell/config/uiplugins';
export default {
emits: ['closed'],
@@ -107,8 +107,9 @@ export default {
endpoint: url,
noCache: true,
metadata: {
- developer: 'true',
- direct: 'true'
+ developer: 'true',
+ direct: 'true',
+ [UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_VERSION]: '>= 3',
},
noAuth: true
}
diff --git a/shell/pages/c/_cluster/uiplugins/PluginInfoPanel.vue b/shell/pages/c/_cluster/uiplugins/PluginInfoPanel.vue
index fe0f78a3224..9f6598eb97c 100644
--- a/shell/pages/c/_cluster/uiplugins/PluginInfoPanel.vue
+++ b/shell/pages/c/_cluster/uiplugins/PluginInfoPanel.vue
@@ -181,12 +181,6 @@ export default {
- + {{ plugin.installedError }}