@rancher/shell 3.0.8-rc.8 → 3.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apis/impl/apis.ts +61 -0
- package/apis/index.ts +40 -0
- package/apis/intf/modal.ts +90 -0
- package/apis/intf/shell.ts +36 -0
- package/apis/intf/slide-in.ts +98 -0
- package/apis/intf/system.ts +41 -0
- package/apis/shell/__tests__/modal.test.ts +80 -0
- package/apis/shell/__tests__/notifications.test.ts +71 -0
- package/apis/shell/__tests__/slide-in.test.ts +54 -0
- package/apis/shell/__tests__/system.test.ts +129 -0
- package/apis/shell/index.ts +38 -0
- package/apis/shell/modal.ts +41 -0
- package/apis/shell/notifications.ts +65 -0
- package/apis/shell/slide-in.ts +33 -0
- package/apis/shell/system.ts +65 -0
- package/apis/vue-shim.d.ts +11 -0
- package/assets/brand/suse/dark/rancher-logo.svg +1 -64
- package/assets/styles/global/_tooltip.scss +6 -1
- package/assets/translations/en-us.yaml +14 -1
- package/components/ActionMenuShell.vue +3 -1
- package/components/BackLink.vue +8 -0
- package/components/BannerGraphic.vue +1 -5
- package/components/BrandImage.vue +17 -6
- package/components/Cron/CronExpressionEditor.vue +1 -1
- package/components/Cron/CronExpressionEditorModal.vue +1 -1
- package/components/CruResource.vue +8 -1
- package/components/Drawer/ResourceDetailDrawer/ConfigTab.vue +1 -0
- package/components/Drawer/ResourceDetailDrawer/__tests__/composables.test.ts +50 -1
- package/components/Drawer/ResourceDetailDrawer/composables.ts +19 -0
- package/components/Drawer/ResourceDetailDrawer/index.vue +4 -1
- package/components/Drawer/ResourceDetailDrawer/types.ts +2 -1
- package/components/LocaleSelector.vue +2 -2
- package/components/ModalManager.vue +11 -1
- package/components/Questions/__tests__/Yaml.test.ts +1 -1
- package/components/Questions/__tests__/index.test.ts +159 -0
- package/components/RelatedResources.vue +5 -0
- package/components/Resource/Detail/Metadata/Annotations/index.vue +2 -2
- package/components/Resource/Detail/Metadata/Labels/index.vue +2 -2
- package/components/Resource/Detail/Metadata/index.vue +3 -3
- package/components/Resource/Detail/ResourcePopover/index.vue +5 -1
- package/components/Resource/Detail/composables.ts +2 -2
- package/components/ResourceDetail/Masthead/latest.vue +23 -21
- package/components/ResourceDetail/index.vue +3 -0
- package/components/ResourceTable.vue +54 -21
- package/components/SlideInPanelManager.vue +16 -11
- package/components/SortableTable/THead.vue +2 -1
- package/components/SortableTable/index.vue +20 -2
- package/components/Tabbed/__tests__/index.test.ts +86 -0
- package/components/Tabbed/index.vue +37 -2
- package/components/__tests__/NamespaceFilter.test.ts +49 -0
- package/components/auth/SelectPrincipal.vue +28 -6
- package/components/auth/__tests__/SelectPrincipal.test.ts +119 -0
- package/components/auth/login/ldap.vue +3 -3
- package/components/fleet/FleetSecretSelector.vue +1 -1
- package/components/form/KeyValue.vue +1 -1
- package/components/form/NameNsDescription.vue +1 -1
- package/components/form/NodeScheduling.vue +2 -2
- package/components/form/ResourceTabs/composable.ts +2 -2
- package/components/form/ResourceTabs/index.vue +0 -2
- package/components/form/__tests__/NameNsDescription.test.ts +42 -0
- package/components/formatter/InternalExternalIP.vue +4 -1
- package/components/formatter/LinkName.vue +5 -0
- package/components/formatter/__tests__/InternalExternalIP.test.ts +1 -1
- package/components/nav/Group.vue +25 -7
- package/components/nav/Header.vue +1 -1
- package/components/nav/NamespaceFilter.vue +1 -0
- package/components/nav/Type.vue +17 -6
- package/components/nav/WindowManager/panels/TabBodyContainer.vue +1 -1
- package/components/nav/__tests__/Type.test.ts +59 -0
- package/components/templates/standalone.vue +1 -1
- package/composables/cruResource.ts +27 -0
- package/composables/focusTrap.ts +3 -1
- package/composables/resourceDetail.ts +15 -0
- package/composables/useI18n.ts +10 -1
- package/composables/useLabeledFormElement.ts +3 -4
- package/config/__test__/uiplugins.test.ts +309 -0
- package/config/labels-annotations.js +1 -0
- package/config/product/explorer.js +3 -1
- package/config/product/fleet.js +1 -1
- package/config/router/navigation-guards/clusters.js +3 -3
- package/config/router/navigation-guards/products.js +1 -1
- package/config/router/routes.js +7 -7
- package/config/types.js +7 -0
- package/config/uiplugins.js +46 -2
- package/core/__tests__/extension-manager-impl.test.js +437 -0
- package/core/extension-manager-impl.js +21 -25
- package/core/plugin-helpers.ts +2 -2
- package/core/plugin.ts +9 -1
- package/core/plugins-loader.js +2 -2
- package/core/types-provisioning.ts +5 -1
- package/core/types.ts +35 -0
- package/detail/provisioning.cattle.io.cluster.vue +9 -6
- package/dialog/DeveloperLoadExtensionDialog.vue +13 -4
- package/dialog/MoveNamespaceDialog.vue +20 -4
- package/dialog/RollbackWorkloadDialog.vue +2 -5
- package/dialog/SearchDialog.vue +1 -0
- package/dialog/__tests__/MoveNamespaceDialog.test.ts +249 -0
- package/directives/__tests__/clean-tooltip.test.ts +298 -0
- package/directives/clean-tooltip.ts +234 -0
- package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +2 -2
- package/edit/__tests__/fleet.cattle.io.helmop.test.ts +100 -3
- package/edit/autoscaling.horizontalpodautoscaler/index.vue +1 -0
- package/edit/configmap.vue +1 -0
- package/edit/constraints.gatekeeper.sh.constraint/index.vue +1 -0
- package/edit/fleet.cattle.io.helmop.vue +11 -6
- package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
- package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +1 -0
- package/edit/logging-flow/index.vue +1 -0
- package/edit/logging.banzaicloud.io.output/index.vue +1 -0
- package/edit/management.cattle.io.fleetworkspace.vue +1 -1
- package/edit/management.cattle.io.project.vue +1 -0
- package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +4 -1
- package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +2 -1
- package/edit/monitoring.coreos.com.prometheusrule/index.vue +1 -0
- package/edit/monitoring.coreos.com.receiver/index.vue +2 -1
- package/edit/monitoring.coreos.com.route.vue +1 -1
- package/edit/namespace.vue +1 -0
- package/edit/networking.istio.io.destinationrule/index.vue +1 -0
- package/edit/networking.k8s.io.ingress/index.vue +1 -0
- package/edit/networking.k8s.io.networkpolicy/PolicyRules.vue +1 -0
- package/edit/networking.k8s.io.networkpolicy/index.vue +1 -0
- package/edit/node.vue +1 -0
- package/edit/persistentvolume/index.vue +27 -22
- package/edit/persistentvolume/plugins/awsElasticBlockStore.vue +13 -14
- package/edit/persistentvolume/plugins/azureDisk.vue +49 -48
- package/edit/persistentvolume/plugins/azureFile.vue +15 -14
- package/edit/persistentvolume/plugins/cephfs.vue +15 -14
- package/edit/persistentvolume/plugins/cinder.vue +15 -14
- package/edit/persistentvolume/plugins/csi.vue +18 -16
- package/edit/persistentvolume/plugins/fc.vue +13 -14
- package/edit/persistentvolume/plugins/flexVolume.vue +15 -14
- package/edit/persistentvolume/plugins/flocker.vue +1 -3
- package/edit/persistentvolume/plugins/gcePersistentDisk.vue +13 -14
- package/edit/persistentvolume/plugins/glusterfs.vue +15 -14
- package/edit/persistentvolume/plugins/hostPath.vue +40 -39
- package/edit/persistentvolume/plugins/iscsi.vue +13 -14
- package/edit/persistentvolume/plugins/local.vue +1 -3
- package/edit/persistentvolume/plugins/longhorn.vue +23 -22
- package/edit/persistentvolume/plugins/nfs.vue +15 -14
- package/edit/persistentvolume/plugins/photonPersistentDisk.vue +1 -14
- package/edit/persistentvolume/plugins/portworxVolume.vue +15 -14
- package/edit/persistentvolume/plugins/quobyte.vue +15 -14
- package/edit/persistentvolume/plugins/rbd.vue +15 -14
- package/edit/persistentvolume/plugins/scaleIO.vue +15 -14
- package/edit/persistentvolume/plugins/storageos.vue +15 -14
- package/edit/persistentvolume/plugins/vsphereVolume.vue +1 -3
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +21 -21
- package/edit/provisioning.cattle.io.cluster/index.vue +5 -5
- package/edit/provisioning.cattle.io.cluster/rke2.vue +9 -8
- package/edit/resources.cattle.io.restore.vue +1 -1
- package/edit/secret/index.vue +1 -1
- package/edit/service.vue +1 -0
- package/edit/serviceaccount.vue +1 -0
- package/edit/storage.k8s.io.storageclass/index.vue +1 -0
- package/edit/workload/Job.vue +2 -2
- package/edit/workload/index.vue +2 -1
- package/edit/workload/mixins/workload.js +1 -1
- package/initialize/App.vue +4 -4
- package/initialize/install-plugins.js +19 -5
- package/machine-config/azure.vue +1 -1
- package/machine-config/components/GCEImage.vue +1 -1
- package/mixins/__tests__/brand.spec.ts +2 -2
- package/mixins/brand.js +1 -7
- package/mixins/create-edit-view/index.js +5 -0
- package/models/__tests__/provisioning.cattle.io.cluster.test.ts +128 -5
- package/models/chart.js +70 -74
- package/models/management.cattle.io.cluster.js +21 -3
- package/models/provisioning.cattle.io.cluster.js +31 -11
- package/package.json +11 -10
- package/pages/auth/login.vue +4 -6
- package/pages/auth/setup.vue +1 -1
- package/pages/auth/verify.vue +3 -3
- package/pages/c/_cluster/apps/charts/__tests__/chart.test.ts +135 -0
- package/pages/c/_cluster/apps/charts/chart.vue +33 -15
- package/pages/c/_cluster/apps/charts/index.vue +122 -24
- package/pages/c/_cluster/apps/charts/install.vue +33 -0
- package/pages/c/_cluster/explorer/__tests__/index.test.ts +1 -1
- package/pages/c/_cluster/explorer/index.vue +8 -6
- package/pages/c/_cluster/fleet/index.vue +4 -7
- package/pages/c/_cluster/manager/hostedprovider/index.vue +12 -6
- package/pages/c/_cluster/settings/brand.vue +1 -1
- package/pages/c/_cluster/settings/index.vue +5 -0
- package/pages/c/_cluster/uiplugins/__tests__/index.test.ts +7 -0
- package/pages/c/_cluster/uiplugins/catalogs.vue +147 -0
- package/pages/c/_cluster/uiplugins/index.vue +126 -184
- package/pkg/auto-import.js +3 -3
- package/pkg/dynamic-importer.lib.js +1 -1
- package/pkg/import.js +1 -1
- package/plugins/__tests__/mutations.tests.ts +179 -0
- package/plugins/dashboard-client-init.js +3 -0
- package/plugins/dashboard-store/getters.js +19 -2
- package/plugins/dashboard-store/model-loader.js +1 -1
- package/plugins/dashboard-store/mutations.js +23 -2
- package/plugins/dashboard-store/resource-class.js +11 -5
- package/plugins/i18n.js +8 -0
- package/plugins/plugin.js +2 -2
- package/plugins/steve/__tests__/steve-pagination-utils.test.ts +506 -0
- package/plugins/steve/steve-class.js +1 -1
- package/plugins/steve/steve-pagination-utils.ts +131 -47
- package/rancher-components/Form/Checkbox/Checkbox.vue +1 -1
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +1 -1
- package/rancher-components/Pill/RcStatusBadge/RcStatusBadge.vue +6 -42
- package/rancher-components/Pill/RcStatusBadge/index.ts +0 -1
- package/rancher-components/Pill/RcStatusBadge/types.ts +1 -1
- package/rancher-components/Pill/RcStatusIndicator/RcStatusIndicator.vue +5 -28
- package/rancher-components/Pill/RcStatusIndicator/types.ts +2 -1
- package/rancher-components/Pill/types.ts +0 -1
- package/rancher-components/RcDropdown/useDropdownContext.ts +2 -4
- package/rancher-components/RcIcon/RcIcon.test.ts +51 -0
- package/rancher-components/RcIcon/RcIcon.vue +46 -0
- package/rancher-components/RcIcon/index.ts +1 -0
- package/rancher-components/RcIcon/types.ts +160 -0
- package/rancher-components/RcItemCard/RcItemCard.vue +1 -1
- package/rancher-components/utils/status.test.ts +67 -0
- package/rancher-components/utils/status.ts +77 -0
- package/scripts/publish-shell.sh +25 -0
- package/scripts/typegen.sh +1 -0
- package/store/__tests__/catalog.test.ts +1 -1
- package/store/__tests__/type-map.test.ts +164 -2
- package/store/action-menu.js +8 -0
- package/store/auth.js +25 -13
- package/store/catalog.js +6 -0
- package/store/i18n.js +3 -3
- package/store/index.js +8 -6
- package/store/notifications.ts +2 -0
- package/store/prefs.js +6 -7
- package/store/type-map.js +17 -7
- package/store/wm.ts +4 -4
- package/types/internal-api/shell/modal.d.ts +6 -6
- package/types/notifications/index.ts +126 -15
- package/types/rancher/index.d.ts +9 -0
- package/types/shell/index.d.ts +54 -3
- package/types/store/__tests__/pagination.types.spec.ts +137 -0
- package/types/store/pagination.types.ts +157 -9
- package/types/vue-shim.d.ts +5 -4
- package/utils/__tests__/provider.test.ts +98 -0
- package/utils/__tests__/router.test.js +238 -0
- package/utils/__tests__/selector-typed.test.ts +263 -0
- package/utils/cluster.js +4 -1
- package/utils/color.js +1 -1
- package/utils/dynamic-content/__tests__/info.test.ts +6 -0
- package/utils/dynamic-content/info.ts +43 -0
- package/utils/favicon.js +4 -4
- package/utils/fleet.ts +8 -1
- package/utils/pagination-utils.ts +2 -2
- package/utils/pagination-wrapper.ts +1 -1
- package/utils/provider.ts +14 -0
- package/utils/router.js +50 -0
- package/utils/selector-typed.ts +6 -2
- package/utils/unit-tests/pagination-utils.spec.ts +8 -8
- package/vue.config.js +3 -3
- package/composables/useExtensionManager.ts +0 -17
- package/core/plugins.js +0 -38
- package/directives/clean-tooltip.js +0 -32
- package/plugins/internal-api/index.ts +0 -37
- package/plugins/internal-api/shared/base-api.ts +0 -13
- package/plugins/internal-api/shell/shell.api.ts +0 -108
- package/plugins/nuxt-client-init.js +0 -3
- package/types/internal-api/shell/growl.d.ts +0 -25
- package/types/internal-api/shell/slideIn.d.ts +0 -15
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import {
|
|
2
|
+
UI_PLUGIN_ANNOTATION,
|
|
3
|
+
UI_PLUGIN_CHART_ANNOTATIONS,
|
|
4
|
+
EXTENSIONS_INCOMPATIBILITY_TYPES,
|
|
5
|
+
isUIPlugin,
|
|
6
|
+
uiPluginHasAnnotation,
|
|
7
|
+
parseRancherVersion,
|
|
8
|
+
// shouldNotLoadPlugin, this is required per test so that we can mock semver.coerce
|
|
9
|
+
isSupportedChartVersion,
|
|
10
|
+
isChartVersionHigher
|
|
11
|
+
} from '@shell/config/uiplugins';
|
|
12
|
+
|
|
13
|
+
import * as VersionModule from '@shell/config/version';
|
|
14
|
+
|
|
15
|
+
let semver;
|
|
16
|
+
let originalCoerce: any;
|
|
17
|
+
const MOCK_API_VERSION = '33.33.33';
|
|
18
|
+
|
|
19
|
+
describe('uiPlugins Config methods', () => {
|
|
20
|
+
describe('fx: isUIPlugin', () => {
|
|
21
|
+
const pluginChart = { versions: [{ annotations: { [UI_PLUGIN_ANNOTATION.NAME]: UI_PLUGIN_ANNOTATION.VALUE } }, { annotations: {} }] };
|
|
22
|
+
|
|
23
|
+
it('should return true if any version has the UI plugin annotation', () => {
|
|
24
|
+
expect(isUIPlugin(pluginChart)).toBe(true);
|
|
25
|
+
});
|
|
26
|
+
it('should return false if chart is null/undefined', () => {
|
|
27
|
+
expect(isUIPlugin(null)).toBe(false);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
describe('fx: uiPluginHasAnnotation', () => {
|
|
32
|
+
const version1 = { annotations: { [UI_PLUGIN_ANNOTATION.NAME]: UI_PLUGIN_ANNOTATION.VALUE } };
|
|
33
|
+
const chart = { versions: [version1] };
|
|
34
|
+
|
|
35
|
+
it('should return true if it finds version with annotation and its corresponding value', () => {
|
|
36
|
+
expect(uiPluginHasAnnotation(chart, UI_PLUGIN_ANNOTATION.NAME, UI_PLUGIN_ANNOTATION.VALUE)).toBe(true);
|
|
37
|
+
});
|
|
38
|
+
it('should return false if chart has no version with a given pair of annotation/value', () => {
|
|
39
|
+
expect(uiPluginHasAnnotation(chart, 'bananas', UI_PLUGIN_ANNOTATION.VALUE)).toBe(false);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
describe('fx: parseRancherVersion', () => {
|
|
44
|
+
it('should handle standard version strings', () => {
|
|
45
|
+
expect(parseRancherVersion('v2.8.1')).toBe('2.8.1');
|
|
46
|
+
});
|
|
47
|
+
it('should apply .999 patch for RC versions', () => {
|
|
48
|
+
expect(parseRancherVersion('v2.8.1-rc1')).toBe('2.8.999');
|
|
49
|
+
});
|
|
50
|
+
it('should apply .999 patch for "head" versions', () => {
|
|
51
|
+
expect(parseRancherVersion('2.8.0-head')).toBe('2.8.999');
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const PLUGIN_NAME = 'test-plugin';
|
|
56
|
+
|
|
57
|
+
const basePluginResource = {
|
|
58
|
+
name: PLUGIN_NAME,
|
|
59
|
+
version: '1.0.0',
|
|
60
|
+
endpoint: '/some/path',
|
|
61
|
+
metadata: { [UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_VERSION]: '>=1.0.0' }
|
|
62
|
+
};
|
|
63
|
+
const compatibleEnv = {
|
|
64
|
+
rancherVersion: '2.7.5',
|
|
65
|
+
kubeVersion: 'v1.25.10',
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
describe('fx: shouldNotLoadPlugin', () => {
|
|
69
|
+
beforeEach(() => {
|
|
70
|
+
jest.resetModules();
|
|
71
|
+
process.env.UI_EXTENSIONS_API_VERSION = MOCK_API_VERSION;
|
|
72
|
+
|
|
73
|
+
semver = require('semver');
|
|
74
|
+
originalCoerce = semver.coerce;
|
|
75
|
+
|
|
76
|
+
jest.spyOn(semver, 'coerce').mockImplementation((v) => {
|
|
77
|
+
if (v === MOCK_API_VERSION) {
|
|
78
|
+
return { version: '3.0.0' };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Use the original for all other inputs (Rancher, Kube)
|
|
82
|
+
return originalCoerce(v);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
afterEach(() => {
|
|
87
|
+
jest.restoreAllMocks();
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('should return false when compatible', () => {
|
|
91
|
+
const { shouldNotLoadPlugin } = require('./../uiplugins');
|
|
92
|
+
|
|
93
|
+
expect(shouldNotLoadPlugin(basePluginResource, compatibleEnv, [])).toBe(false);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('should return "plugins.error.api" if Extensions API version is incompatible', () => {
|
|
97
|
+
const { shouldNotLoadPlugin } = require('./../uiplugins');
|
|
98
|
+
|
|
99
|
+
const incompatibleApiPlugin = {
|
|
100
|
+
...basePluginResource,
|
|
101
|
+
metadata: { [UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_VERSION]: '>=4.0.0' }
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
expect(shouldNotLoadPlugin(incompatibleApiPlugin, compatibleEnv, [])).toBe('plugins.error.api');
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('should return "plugins.error.primeOnly" if extension is Prime-only and Rancher is not Prime', () => {
|
|
108
|
+
const { shouldNotLoadPlugin } = require('./../uiplugins');
|
|
109
|
+
|
|
110
|
+
jest.spyOn(VersionModule, 'isRancherPrime').mockReturnValue(false);
|
|
111
|
+
|
|
112
|
+
const incompatibleApiPlugin = {
|
|
113
|
+
...basePluginResource,
|
|
114
|
+
metadata: {
|
|
115
|
+
[UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_VERSION]: '>=1.0.0',
|
|
116
|
+
[UI_PLUGIN_CHART_ANNOTATIONS.PRIME_ONLY]: 'true'
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
expect(shouldNotLoadPlugin(incompatibleApiPlugin, compatibleEnv, [])).toBe('plugins.error.primeOnly');
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('should return "plugins.error.host" if HOST application value is incompatible', () => {
|
|
124
|
+
const { shouldNotLoadPlugin } = require('./../uiplugins');
|
|
125
|
+
|
|
126
|
+
const incompatibleApiPlugin = {
|
|
127
|
+
...basePluginResource,
|
|
128
|
+
metadata: {
|
|
129
|
+
[UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_VERSION]: '>=1.0.0',
|
|
130
|
+
[UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_HOST]: 'rancher-dummy-host'
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
expect(shouldNotLoadPlugin(incompatibleApiPlugin, compatibleEnv, [])).toBe('plugins.error.host');
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('should return "plugins.error.kubeVersion" if incompatible', () => {
|
|
138
|
+
const { shouldNotLoadPlugin } = require('./../uiplugins');
|
|
139
|
+
|
|
140
|
+
const incompatibleApiPlugin = {
|
|
141
|
+
...basePluginResource,
|
|
142
|
+
metadata: {
|
|
143
|
+
[UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_VERSION]: '>=1.0.0',
|
|
144
|
+
[UI_PLUGIN_CHART_ANNOTATIONS.KUBE_VERSION]: '>= 2.0.0'
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
expect(shouldNotLoadPlugin(incompatibleApiPlugin, compatibleEnv, [])).toBe('plugins.error.kubeVersion');
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('should return "plugins.error.version" if incompatible', () => {
|
|
152
|
+
const { shouldNotLoadPlugin } = require('./../uiplugins');
|
|
153
|
+
|
|
154
|
+
const incompatibleApiPlugin = {
|
|
155
|
+
...basePluginResource,
|
|
156
|
+
metadata: {
|
|
157
|
+
[UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_VERSION]: '>=1.0.0',
|
|
158
|
+
[UI_PLUGIN_CHART_ANNOTATIONS.RANCHER_VERSION]: '>= 3.0.0'
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
expect(shouldNotLoadPlugin(incompatibleApiPlugin, compatibleEnv, [])).toBe('plugins.error.version');
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('should return "plugins.error.developerPkg" if a builtin extension with the same name was loaded first', () => {
|
|
166
|
+
const { shouldNotLoadPlugin } = require('./../uiplugins');
|
|
167
|
+
|
|
168
|
+
const incompatibleApiPlugin = {
|
|
169
|
+
...basePluginResource,
|
|
170
|
+
metadata: { [UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_VERSION]: '>=1.0.0' }
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
expect(shouldNotLoadPlugin(incompatibleApiPlugin, compatibleEnv, [{ name: PLUGIN_NAME, builtin: true }])).toBe('plugins.error.developerPkg');
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
describe('fx: isSupportedChartVersion', () => {
|
|
178
|
+
beforeEach(() => {
|
|
179
|
+
jest.resetModules();
|
|
180
|
+
process.env.UI_EXTENSIONS_API_VERSION = MOCK_API_VERSION;
|
|
181
|
+
|
|
182
|
+
semver = require('semver');
|
|
183
|
+
originalCoerce = semver.coerce;
|
|
184
|
+
|
|
185
|
+
jest.spyOn(semver, 'coerce').mockImplementation((v) => {
|
|
186
|
+
if (v === MOCK_API_VERSION) {
|
|
187
|
+
return { version: '3.0.0' };
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Use the original for all other inputs (Rancher, Kube)
|
|
191
|
+
return originalCoerce(v);
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
afterEach(() => {
|
|
196
|
+
jest.restoreAllMocks();
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
const versionData = {
|
|
200
|
+
rancherVersion: 'v2.7.5',
|
|
201
|
+
kubeVersion: 'v1.25.10',
|
|
202
|
+
version: '1.0.0'
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
it('should return "isVersionCompatible" true when compatible', () => {
|
|
206
|
+
const { isSupportedChartVersion } = require('./../uiplugins');
|
|
207
|
+
|
|
208
|
+
const annotations = {
|
|
209
|
+
[UI_PLUGIN_CHART_ANNOTATIONS.KUBE_VERSION]: '>=1.0.0',
|
|
210
|
+
[UI_PLUGIN_CHART_ANNOTATIONS.RANCHER_VERSION]: '>=2.0.0',
|
|
211
|
+
[UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_VERSION]: '>=2.0.0'
|
|
212
|
+
};
|
|
213
|
+
const data = { ...versionData, version: { annotations } };
|
|
214
|
+
const result = isSupportedChartVersion(data, true);
|
|
215
|
+
|
|
216
|
+
expect(result.isVersionCompatible).toBe(true);
|
|
217
|
+
expect(result.versionIncompatibilityData).toStrictEqual({});
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it('should return incompatibility object for kube version mismatch', () => {
|
|
221
|
+
const annotations = { [UI_PLUGIN_CHART_ANNOTATIONS.KUBE_VERSION]: '>=2.0.0' };
|
|
222
|
+
const data = { ...versionData, version: { annotations } };
|
|
223
|
+
const result = isSupportedChartVersion(data, true);
|
|
224
|
+
|
|
225
|
+
expect(result.isVersionCompatible).toBe(false);
|
|
226
|
+
expect(result.versionIncompatibilityData.type).toBe(EXTENSIONS_INCOMPATIBILITY_TYPES.KUBE);
|
|
227
|
+
expect(result.versionIncompatibilityData.required).toBe('>=2.0.0');
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it('should return incompatibility object for Rancher version mismatch', () => {
|
|
231
|
+
const annotations = { [UI_PLUGIN_CHART_ANNOTATIONS.RANCHER_VERSION]: '>=3.0.0' };
|
|
232
|
+
const data = { ...versionData, version: { annotations } };
|
|
233
|
+
const result = isSupportedChartVersion(data, true);
|
|
234
|
+
|
|
235
|
+
expect(result.isVersionCompatible).toBe(false);
|
|
236
|
+
expect(result.versionIncompatibilityData.type).toBe(EXTENSIONS_INCOMPATIBILITY_TYPES.UI);
|
|
237
|
+
expect(result.versionIncompatibilityData.required).toBe('>=3.0.0');
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
it('should return incompatibility object for UI version mismatch', () => {
|
|
241
|
+
const annotations = { [UI_PLUGIN_CHART_ANNOTATIONS.UI_VERSION]: '>=3.0.0' };
|
|
242
|
+
const data = { ...versionData, version: { annotations } };
|
|
243
|
+
const result = isSupportedChartVersion(data, true);
|
|
244
|
+
|
|
245
|
+
expect(result.isVersionCompatible).toBe(false);
|
|
246
|
+
expect(result.versionIncompatibilityData.type).toBe(EXTENSIONS_INCOMPATIBILITY_TYPES.UI);
|
|
247
|
+
expect(result.versionIncompatibilityData.required).toBe('>=3.0.0');
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
it('should return incompatibility object for extensions api missing', () => {
|
|
251
|
+
const annotations = {};
|
|
252
|
+
const data = { ...versionData, version: { annotations } };
|
|
253
|
+
const result = isSupportedChartVersion(data, true);
|
|
254
|
+
|
|
255
|
+
expect(result.isVersionCompatible).toBe(false);
|
|
256
|
+
expect(result.versionIncompatibilityData.type).toBe(EXTENSIONS_INCOMPATIBILITY_TYPES.EXTENSIONS_API_MISSING);
|
|
257
|
+
expect(result.versionIncompatibilityData.required).toBeUndefined();
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it('should return incompatibility object for extensions API version mismatch', () => {
|
|
261
|
+
const { isSupportedChartVersion } = require('./../uiplugins');
|
|
262
|
+
|
|
263
|
+
const annotations = { [UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_VERSION]: '>=4.0.0' };
|
|
264
|
+
const data = { ...versionData, version: { annotations } };
|
|
265
|
+
const result = isSupportedChartVersion(data, true);
|
|
266
|
+
|
|
267
|
+
expect(result.isVersionCompatible).toBe(false);
|
|
268
|
+
expect(result.versionIncompatibilityData.type).toBe(EXTENSIONS_INCOMPATIBILITY_TYPES.EXTENSIONS_API);
|
|
269
|
+
expect(result.versionIncompatibilityData.required).toBe('>=4.0.0');
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
it('should return incompatibility object for HOST_APP mismatch', () => {
|
|
273
|
+
const { isSupportedChartVersion } = require('./../uiplugins');
|
|
274
|
+
|
|
275
|
+
const annotations = { [UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_VERSION]: '>=1.0.0 < 5.0.0', [UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_HOST]: 'rancher-dummy-host' };
|
|
276
|
+
const data = { ...versionData, version: { annotations } };
|
|
277
|
+
const result = isSupportedChartVersion(data, true);
|
|
278
|
+
|
|
279
|
+
expect(result.isVersionCompatible).toBe(false);
|
|
280
|
+
expect(result.versionIncompatibilityData.type).toBe(EXTENSIONS_INCOMPATIBILITY_TYPES.HOST);
|
|
281
|
+
expect(result.versionIncompatibilityData.required).toBe('rancher-dummy-host');
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
it('should return incompatibility object for Prime only extension running in non-prime env', () => {
|
|
285
|
+
const { isSupportedChartVersion } = require('./../uiplugins');
|
|
286
|
+
|
|
287
|
+
jest.spyOn(VersionModule, 'isRancherPrime').mockReturnValue(false);
|
|
288
|
+
|
|
289
|
+
const annotations = { [UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_VERSION]: '>=1.0.0 < 5.0.0', [UI_PLUGIN_CHART_ANNOTATIONS.PRIME_ONLY]: 'true' };
|
|
290
|
+
const data = { ...versionData, version: { annotations } };
|
|
291
|
+
const result = isSupportedChartVersion(data, true);
|
|
292
|
+
|
|
293
|
+
expect(result.isVersionCompatible).toBe(false);
|
|
294
|
+
expect(result.versionIncompatibilityData.type).toBe(EXTENSIONS_INCOMPATIBILITY_TYPES.PRIME_ONLY);
|
|
295
|
+
expect(result.versionIncompatibilityData.required).toBe(true);
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
describe('fx: isChartVersionHigher', () => {
|
|
300
|
+
// Tests now rely on the actual semver.gt implementation
|
|
301
|
+
it('should return true when version A is higher', () => {
|
|
302
|
+
expect(isChartVersionHigher('2.1.0', '2.0.0')).toBe(true);
|
|
303
|
+
});
|
|
304
|
+
it('should return false when version A is lower or equal', () => {
|
|
305
|
+
expect(isChartVersionHigher('2.0.0', '2.1.0')).toBe(false);
|
|
306
|
+
expect(isChartVersionHigher('2.0.0', '2.0.0')).toBe(false);
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
});
|
|
@@ -85,6 +85,7 @@ export const CATALOG = {
|
|
|
85
85
|
_PARTNER: 'partner',
|
|
86
86
|
_OTHER: 'other',
|
|
87
87
|
|
|
88
|
+
PRIME_ONLY: 'catalog.cattle.io/prime-only',
|
|
88
89
|
EXPERIMENTAL: 'catalog.cattle.io/experimental',
|
|
89
90
|
NAMESPACE: 'catalog.cattle.io/namespace',
|
|
90
91
|
RELEASE_NAME: 'catalog.cattle.io/release-name',
|
|
@@ -180,7 +180,8 @@ export function init(store) {
|
|
|
180
180
|
mapGroup(/^(.*\.)?(scc)\.cattle\.io$/, 'SCC');
|
|
181
181
|
|
|
182
182
|
const dePaginateBindings = configureConditionalDepaginate({ maxResourceCount: 5000 });
|
|
183
|
-
const dePaginateNormanBindings = configureConditionalDepaginate({ maxResourceCount: 5000, isNorman: true })
|
|
183
|
+
const dePaginateNormanBindings = configureConditionalDepaginate({ maxResourceCount: 5000, isNorman: true });
|
|
184
|
+
const dePaginateNormanUsers = configureConditionalDepaginate({ maxResourceCount: 5000, isNorman: true });
|
|
184
185
|
|
|
185
186
|
configureType(NODE, { isCreatable: false, isEditable: true });
|
|
186
187
|
configureType(WORKLOAD_TYPES.JOB, { isEditable: false, match: WORKLOAD_TYPES.JOB });
|
|
@@ -189,6 +190,7 @@ export function init(store) {
|
|
|
189
190
|
configureType(MANAGEMENT.PROJECT, { displayName: store.getters['i18n/t']('namespace.project.label') });
|
|
190
191
|
configureType(NORMAN.CLUSTER_ROLE_TEMPLATE_BINDING, { depaginate: dePaginateNormanBindings });
|
|
191
192
|
configureType(NORMAN.PROJECT_ROLE_TEMPLATE_BINDING, { depaginate: dePaginateNormanBindings });
|
|
193
|
+
configureType(NORMAN.USER, { depaginate: dePaginateNormanUsers });
|
|
192
194
|
configureType(SNAPSHOT, { depaginate: true });
|
|
193
195
|
|
|
194
196
|
configureType(SECRET, { showListMasthead: false });
|
package/config/product/fleet.js
CHANGED
|
@@ -30,12 +30,12 @@ export async function loadClusters(to, from, next, { store }) {
|
|
|
30
30
|
const oldPkg = getPackageFromRoute(from);
|
|
31
31
|
const oldProduct = getProductFromRoute(from);
|
|
32
32
|
|
|
33
|
-
// TODO: Replace all references to store.$
|
|
33
|
+
// TODO: Replace all references to store.$extension.
|
|
34
34
|
// Unfortunately the initialization code has circular dependencies between creating
|
|
35
35
|
// the router and creating the store that will need to be untangled before this can be tackled.
|
|
36
36
|
|
|
37
37
|
// Leave an old pkg where we weren't before?
|
|
38
|
-
const oldPkgPlugin = oldPkg ? Object.values(store.$
|
|
38
|
+
const oldPkgPlugin = oldPkg ? Object.values(store.$extension.getPlugins()).find((p) => p.name === oldPkg) : null;
|
|
39
39
|
|
|
40
40
|
if (oldPkg && oldPkg !== pkg ) {
|
|
41
41
|
// Execute anything optional the plugin wants to. For example resetting it's store to remove data
|
|
@@ -53,7 +53,7 @@ export async function loadClusters(to, from, next, { store }) {
|
|
|
53
53
|
];
|
|
54
54
|
|
|
55
55
|
// Entering a new package where we weren't before?
|
|
56
|
-
const newPkgPlugin = pkg ? Object.values(store.$
|
|
56
|
+
const newPkgPlugin = pkg ? Object.values(store.$extension.getPlugins()).find((p) => p.name === pkg) : null;
|
|
57
57
|
|
|
58
58
|
// Note - We can't block on oldPkg !== newPkg because on a fresh load the `from` route equals the `to` route
|
|
59
59
|
if (pkg && (oldPkg !== pkg || from.fullPath === to.fullPath)) {
|
|
@@ -9,7 +9,7 @@ export async function loadProducts(to, from, next, { store }) {
|
|
|
9
9
|
// GC should be notified of route change before any find/get request is made that might be used for that page
|
|
10
10
|
store.dispatch('gcRouteChanged', to);
|
|
11
11
|
|
|
12
|
-
await applyProducts(store, store.$
|
|
12
|
+
await applyProducts(store, store.$extension);
|
|
13
13
|
setProduct(store, to);
|
|
14
14
|
next();
|
|
15
15
|
}
|
package/config/router/routes.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { NAME as APPS } from '@shell/config/product/apps';
|
|
2
|
-
import { NAME as EXPLORER } from '@shell/config/product/explorer';
|
|
3
2
|
import { NAME as MANAGER } from '@shell/config/product/manager';
|
|
4
3
|
import {
|
|
5
4
|
CAPI, MANAGEMENT, BACKUP_RESTORE, COMPLIANCE, VIRTUAL_TYPES
|
|
@@ -81,9 +80,13 @@ export default [
|
|
|
81
80
|
{
|
|
82
81
|
path: '/c/:cluster/uiplugins',
|
|
83
82
|
name: 'c-cluster-uiplugins',
|
|
84
|
-
component: () => interopDefault(import('@shell/pages/c/_cluster/uiplugins/index.vue'))
|
|
83
|
+
component: () => interopDefault(import('@shell/pages/c/_cluster/uiplugins/index.vue'))
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
path: '/c/:cluster/uiplugins/catalogs',
|
|
87
|
+
component: () => interopDefault(import('@shell/pages/c/_cluster/uiplugins/catalogs.vue')),
|
|
88
|
+
name: 'c-cluster-uiplugins-catalogs'
|
|
85
89
|
},
|
|
86
|
-
|
|
87
90
|
{
|
|
88
91
|
path: '/diagnostic',
|
|
89
92
|
component: () => interopDefault(import('@shell/pages/diagnostic.vue')),
|
|
@@ -180,10 +183,7 @@ export default [
|
|
|
180
183
|
redirect(to) {
|
|
181
184
|
return {
|
|
182
185
|
name: 'c-cluster-explorer',
|
|
183
|
-
params: {
|
|
184
|
-
...(to?.params || {}),
|
|
185
|
-
product: EXPLORER,
|
|
186
|
-
}
|
|
186
|
+
params: { ...(to?.params || {}) }
|
|
187
187
|
};
|
|
188
188
|
}
|
|
189
189
|
},
|
package/config/types.js
CHANGED
|
@@ -222,6 +222,13 @@ export const MANAGEMENT = {
|
|
|
222
222
|
OIDC_CLIENT: 'management.cattle.io.oidcclient'
|
|
223
223
|
};
|
|
224
224
|
|
|
225
|
+
export const BRAND = {
|
|
226
|
+
SUSE: 'suse',
|
|
227
|
+
CSP: 'csp',
|
|
228
|
+
FEDERAL: 'federal',
|
|
229
|
+
RGS: 'rgs',
|
|
230
|
+
};
|
|
231
|
+
|
|
225
232
|
export const EXT = { USER_ACTIVITY: 'ext.cattle.io.useractivity' };
|
|
226
233
|
|
|
227
234
|
export const CAPI = {
|
package/config/uiplugins.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import semver from 'semver';
|
|
2
|
+
import { isRancherPrime } from '@shell/config/version';
|
|
2
3
|
|
|
3
4
|
// Version of the plugin API supported
|
|
4
5
|
// here we inject the current shell version that we read in vue.config
|
|
@@ -43,6 +44,7 @@ export const UI_PLUGIN_CHART_ANNOTATIONS = {
|
|
|
43
44
|
EXTENSIONS_HOST: 'catalog.cattle.io/ui-extensions-host',
|
|
44
45
|
DISPLAY_NAME: 'catalog.cattle.io/display-name',
|
|
45
46
|
HIDDEN_BUILTIN: 'catalog.cattle.io/ui-hidden-builtin',
|
|
47
|
+
PRIME_ONLY: 'catalog.cattle.io/prime-only'
|
|
46
48
|
};
|
|
47
49
|
|
|
48
50
|
// Extension catalog labels
|
|
@@ -58,6 +60,7 @@ export const EXTENSIONS_INCOMPATIBILITY_TYPES = {
|
|
|
58
60
|
EXTENSIONS_API: 'extensionsApiVersion',
|
|
59
61
|
KUBE: 'kubeVersion',
|
|
60
62
|
HOST: 'host',
|
|
63
|
+
PRIME_ONLY: 'primeOnly',
|
|
61
64
|
};
|
|
62
65
|
|
|
63
66
|
export const EXTENSIONS_INCOMPATIBILITY_DATA = {
|
|
@@ -87,6 +90,11 @@ export const EXTENSIONS_INCOMPATIBILITY_DATA = {
|
|
|
87
90
|
tooltipKey: 'plugins.info.requiresHost',
|
|
88
91
|
mainHost: UI_PLUGIN_HOST_APP,
|
|
89
92
|
},
|
|
93
|
+
PRIME_ONLY: {
|
|
94
|
+
type: EXTENSIONS_INCOMPATIBILITY_TYPES.PRIME_ONLY,
|
|
95
|
+
cardMessageKey: 'plugins.incompatiblePrimeOnly',
|
|
96
|
+
tooltipKey: 'plugins.info.requiresRancherPrime',
|
|
97
|
+
},
|
|
90
98
|
};
|
|
91
99
|
|
|
92
100
|
export function isUIPlugin(chart) {
|
|
@@ -124,10 +132,29 @@ export function parseRancherVersion(v) {
|
|
|
124
132
|
* Check if a version is incompatible with the current environment
|
|
125
133
|
*/
|
|
126
134
|
function checkIncompatibility(currentVersion, requiredVersion, incompatibilityData, returnObj, versionObj) {
|
|
127
|
-
|
|
135
|
+
let passed = true;
|
|
136
|
+
|
|
137
|
+
switch (incompatibilityData.type) {
|
|
138
|
+
case EXTENSIONS_INCOMPATIBILITY_TYPES.PRIME_ONLY:
|
|
139
|
+
if (requiredVersion && !currentVersion) {
|
|
140
|
+
passed = false;
|
|
141
|
+
}
|
|
142
|
+
break;
|
|
143
|
+
case EXTENSIONS_INCOMPATIBILITY_TYPES.EXTENSIONS_API_MISSING:
|
|
144
|
+
!requiredVersion ? passed = false : passed = true;
|
|
145
|
+
break;
|
|
146
|
+
default:
|
|
147
|
+
if (requiredVersion && !semver.satisfies(currentVersion, requiredVersion)) {
|
|
148
|
+
passed = false;
|
|
149
|
+
}
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (!passed) {
|
|
128
154
|
if (!returnObj) {
|
|
129
155
|
return false;
|
|
130
156
|
}
|
|
157
|
+
|
|
131
158
|
versionObj.isVersionCompatible = false;
|
|
132
159
|
versionObj.versionIncompatibilityData = { ...incompatibilityData, required: requiredVersion };
|
|
133
160
|
|
|
@@ -137,7 +164,7 @@ function checkIncompatibility(currentVersion, requiredVersion, incompatibilityDa
|
|
|
137
164
|
return true;
|
|
138
165
|
}
|
|
139
166
|
|
|
140
|
-
// i18n-uses plugins.error.generic, plugins.error.api, plugins.error.host, plugins.error.kubeVersion, plugins.error.version, plugins.error.developerPkg, plugins.error.apiAnnotationMissing
|
|
167
|
+
// i18n-uses plugins.error.generic, plugins.error.api, plugins.error.host, plugins.error.kubeVersion, plugins.error.version, plugins.error.developerPkg, plugins.error.apiAnnotationMissing, plugins.error.primeOnly
|
|
141
168
|
|
|
142
169
|
/**
|
|
143
170
|
* Whether an extension should be loaded based on the metadata returned by the backend in the UIPlugins resource instance
|
|
@@ -148,6 +175,8 @@ function checkIncompatibility(currentVersion, requiredVersion, incompatibilityDa
|
|
|
148
175
|
* @returns String | Boolean
|
|
149
176
|
*/
|
|
150
177
|
export function shouldNotLoadPlugin(UIPluginResource, { rancherVersion, kubeVersion }, loadedPlugins) {
|
|
178
|
+
const isCurrRancherPrime = isRancherPrime();
|
|
179
|
+
|
|
151
180
|
const {
|
|
152
181
|
name, version, endpoint, compressedEndpoint
|
|
153
182
|
} = UIPluginResource;
|
|
@@ -171,6 +200,13 @@ export function shouldNotLoadPlugin(UIPluginResource, { rancherVersion, kubeVers
|
|
|
171
200
|
return 'plugins.error.api';
|
|
172
201
|
}
|
|
173
202
|
|
|
203
|
+
// Prime only
|
|
204
|
+
const primeOnlyAnnotation = UIPluginResource.metadata?.[UI_PLUGIN_CHART_ANNOTATIONS.PRIME_ONLY] === 'true';
|
|
205
|
+
|
|
206
|
+
if (!isCurrRancherPrime && primeOnlyAnnotation) {
|
|
207
|
+
return 'plugins.error.primeOnly';
|
|
208
|
+
}
|
|
209
|
+
|
|
174
210
|
// Host application
|
|
175
211
|
const requiredHost = UIPluginResource.metadata?.[UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_HOST];
|
|
176
212
|
|
|
@@ -220,10 +256,13 @@ export function shouldNotLoadPlugin(UIPluginResource, { rancherVersion, kubeVers
|
|
|
220
256
|
* @returns Boolean | Object
|
|
221
257
|
*/
|
|
222
258
|
export function isSupportedChartVersion(versionData, returnObj = false) {
|
|
259
|
+
const isCurrRancherPrime = isRancherPrime();
|
|
260
|
+
|
|
223
261
|
const { version, rancherVersion, kubeVersion } = versionData;
|
|
224
262
|
const versionObj = {
|
|
225
263
|
...version, isVersionCompatible: true, versionIncompatibilityData: {}
|
|
226
264
|
};
|
|
265
|
+
|
|
227
266
|
const parsedRancherVersion = rancherVersion ? parseRancherVersion(rancherVersion) : '';
|
|
228
267
|
const parsedUiExtensionsApiVersion = semver.coerce(UI_EXTENSIONS_API_VERSION)?.version;
|
|
229
268
|
|
|
@@ -258,6 +297,11 @@ export function isSupportedChartVersion(versionData, returnObj = false) {
|
|
|
258
297
|
requiredVersion: version.annotations?.[UI_PLUGIN_CHART_ANNOTATIONS.EXTENSIONS_HOST],
|
|
259
298
|
incompatibilityData: EXTENSIONS_INCOMPATIBILITY_DATA.HOST,
|
|
260
299
|
},
|
|
300
|
+
{
|
|
301
|
+
currentVersion: isCurrRancherPrime,
|
|
302
|
+
requiredVersion: version.annotations?.[UI_PLUGIN_CHART_ANNOTATIONS.PRIME_ONLY] === 'true',
|
|
303
|
+
incompatibilityData: EXTENSIONS_INCOMPATIBILITY_DATA.PRIME_ONLY,
|
|
304
|
+
}
|
|
261
305
|
];
|
|
262
306
|
|
|
263
307
|
for (const { currentVersion, requiredVersion, incompatibilityData } of checks) {
|