@rancher/shell 0.1.2 → 0.1.3
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/assets/translations/en-us.yaml +27 -769
- package/assets/translations/zh-hans.yaml +8 -769
- package/components/ActionMenu.vue +3 -3
- package/components/CodeMirror.vue +6 -8
- package/components/CommunityLinks.vue +1 -1
- package/components/ContainerResourceLimit.vue +14 -0
- package/components/ExplorerMembers.vue +123 -0
- package/components/ExplorerProjectsNamespaces.vue +405 -0
- package/components/GrafanaDashboard.vue +17 -2
- package/components/LocaleSelector.vue +81 -0
- package/components/PromptModal.vue +2 -3
- package/components/ResourceList/index.vue +1 -1
- package/components/ResourceTable.vue +3 -6
- package/components/SingleClusterInfo.vue +1 -1
- package/components/SortableTable/index.vue +23 -20
- package/components/SortableTable/selection.js +1 -0
- package/components/auth/AzureWarning.vue +5 -1
- package/components/auth/Principal.vue +1 -1
- package/components/auth/RoleDetailEdit.vue +18 -11
- package/components/fleet/FleetRepos.vue +0 -2
- package/components/form/NameNsDescription.vue +4 -6
- package/components/form/NodeScheduling.vue +1 -1
- package/components/form/WorkloadPorts.vue +1 -1
- package/components/formatter/WorkloadHealthScale.vue +1 -1
- package/components/nav/Header.vue +9 -9
- package/components/nav/NamespaceFilter.vue +7 -4
- package/components/nav/TopLevelMenu.vue +6 -43
- package/components/nav/WindowManager/ContainerLogs.vue +1 -1
- package/config/product/harvester-manager.js +64 -2
- package/config/product/manager.js +9 -0
- package/config/settings.js +17 -71
- package/config/table-headers.js +0 -1
- package/config/types.js +5 -25
- package/core/plugin-routes.ts +34 -22
- package/core/plugin.ts +15 -3
- package/core/plugins-loader.js +2 -0
- package/core/plugins.js +79 -36
- package/core/types.ts +7 -1
- package/detail/provisioning.cattle.io.cluster.vue +13 -0
- package/detail/workload/index.vue +11 -5
- package/{components/dialog → dialog}/AddClusterMemberDialog.vue +0 -0
- package/{components/dialog → dialog}/AddCustomBadgeDialog.vue +0 -0
- package/{components/dialog → dialog}/AddProjectMemberDialog.vue +0 -0
- package/{components/dialog → dialog}/AddonConfigConfirmationDialog.vue +0 -0
- package/{components/dialog → dialog}/DrainNode.vue +0 -0
- package/{components/dialog → dialog}/ForceMachineRemoveDialog.vue +0 -0
- package/{components/dialog → dialog}/GenericPrompt.vue +0 -0
- package/{components/dialog → dialog}/RollbackWorkloadDialog.vue +0 -0
- package/{components/dialog → dialog}/RotateCertificatesDialog.vue +0 -0
- package/{components/dialog → dialog}/RotateEncryptionKeyDialog.vue +0 -0
- package/{components/dialog → dialog}/SaveAsRKETemplateDialog.vue +0 -0
- package/{components/dialog → dialog}/ScaleMachineDownDialog.vue +0 -0
- package/edit/auth/azuread.vue +20 -1
- package/edit/management.cattle.io.project.vue +2 -2
- package/edit/namespace.vue +17 -10
- package/edit/persistentvolumeclaim.vue +1 -0
- package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/MachinePool.vue +33 -5
- package/edit/service.vue +1 -1
- package/edit/workload/index.vue +363 -15
- package/edit/workload/mixins/workload.js +62 -7
- package/edit/workload/storage/persistentVolumeClaim/persistentvolumeclaim.vue +1 -0
- package/layouts/default.vue +52 -27
- package/layouts/error.vue +5 -1
- package/layouts/home.vue +6 -2
- package/list/harvesterhci.io.management.cluster.vue +74 -33
- package/list/namespace.vue +3 -5
- package/machine-config/amazonec2.vue +2 -0
- package/machine-config/harvester.vue +96 -49
- package/middleware/authenticated.js +56 -52
- package/mixins/form-validation.js +1 -1
- package/mixins/resource-fetch.js +3 -1
- package/models/fleet.cattle.io.bundle.js +26 -19
- package/models/harvesterhci.io.management.cluster.js +194 -5
- package/models/management.cattle.io.cluster.js +1 -1
- package/models/management.cattle.io.clusterroletemplatebinding.js +9 -0
- package/models/management.cattle.io.project.js +23 -2
- package/models/namespace.js +19 -3
- package/models/pod.js +19 -2
- package/models/provisioning.cattle.io.cluster.js +4 -0
- package/models/workload.js +4 -243
- package/models/workload.service.js +314 -0
- package/nuxt.config.js +11 -9
- package/package.json +3 -3
- package/pages/auth/login.vue +11 -2
- package/pages/auth/setup.vue +1 -1
- package/pages/c/_cluster/_product/members/index.vue +3 -93
- package/pages/c/_cluster/_product/projectsnamespaces.vue +6 -403
- package/pages/c/_cluster/settings/performance.vue +19 -16
- package/pages/fail-whale.vue +1 -10
- package/pages/index.vue +18 -4
- package/pages/plugins.vue +2 -2
- package/pages/prefs.vue +8 -6
- package/pkg/auto-import.js +44 -7
- package/pkg/dynamic-plugin-loader.js +28 -0
- package/pkg/import.js +2 -2
- package/pkg/model-loader-require.lib.js +3 -0
- package/pkg/vue.config.js +9 -6
- package/plugins/dashboard-store/model-loader-require.js +12 -0
- package/plugins/dashboard-store/model-loader.js +4 -1
- package/plugins/dashboard-store/resource-class.js +10 -3
- package/plugins/steve/actions.js +1 -1
- package/plugins/steve/index.js +6 -4
- package/plugins/steve/subscribe.js +34 -23
- package/rancher-components/Form/Checkbox/Checkbox.test.ts +77 -0
- package/rancher-components/Form/Checkbox/Checkbox.vue +12 -2
- package/scripts/build-pkg.sh +48 -2
- package/scripts/drone-build-pkg.sh +31 -0
- package/scripts/publish-shell.sh +10 -11
- package/scripts/serve-pkgs +17 -10
- package/store/catalog.js +3 -1
- package/store/i18n.js +16 -11
- package/store/index.js +4 -181
- package/store/prefs.js +30 -2
- package/store/type-map.js +16 -29
- package/utils/cluster.js +1 -1
- package/utils/custom-validators.js +1 -12
- package/utils/dynamic-importer.js +1 -1
- package/utils/validators/setting.js +0 -35
- package/components/FilterLabel.vue +0 -254
- package/components/HarvesterUpgradeProgressBarList.vue +0 -109
- package/components/VMConsoleBar.vue +0 -87
- package/components/dialog/harvester/AddHotplugModal.vue +0 -159
- package/components/dialog/harvester/BackupModal.vue +0 -117
- package/components/dialog/harvester/CloneTemplate.vue +0 -125
- package/components/dialog/harvester/EjectCDROMDialog.vue +0 -157
- package/components/dialog/harvester/ExportImageDialog.vue +0 -152
- package/components/dialog/harvester/MaintenanceDialog.vue +0 -94
- package/components/dialog/harvester/MigrationDialog.vue +0 -154
- package/components/dialog/harvester/RestoreDialog.vue +0 -153
- package/components/dialog/harvester/SupportBundle.vue +0 -217
- package/components/dialog/harvester/UnplugVolume.vue +0 -108
- package/components/form/SerialConsole/index.vue +0 -267
- package/components/formatter/AttachVMWithName.vue +0 -46
- package/components/formatter/CloudInitType.vue +0 -27
- package/components/formatter/HarvesterBackupTargetValidation.vue +0 -43
- package/components/formatter/HarvesterCPUUsed.vue +0 -122
- package/components/formatter/HarvesterDiskState.vue +0 -66
- package/components/formatter/HarvesterHostName.vue +0 -66
- package/components/formatter/HarvesterIpAddress.vue +0 -90
- package/components/formatter/HarvesterMemoryUsed.vue +0 -140
- package/components/formatter/HarvesterMigrationState.vue +0 -85
- package/components/formatter/HarvesterNodeName.vue +0 -49
- package/components/formatter/HarvesterStorageUsed.vue +0 -194
- package/components/formatter/HarvesterVmState.vue +0 -123
- package/components/nav/HarvesterUpgrade.vue +0 -232
- package/components/novnc/NovncConsole.vue +0 -93
- package/components/novnc/NovncConsoleItem.vue +0 -89
- package/components/novnc/NovncConsoleWrapper.vue +0 -243
- package/config/harvester-map.js +0 -44
- package/config/harvester-table-headers.js +0 -27
- package/config/product/harvester.js +0 -305
- package/detail/harvesterhci.io.host/HarvesterHostBasic.vue +0 -364
- package/detail/harvesterhci.io.host/HarvesterHostDisk.vue +0 -200
- package/detail/harvesterhci.io.host/HarvesterHostNetwork.vue +0 -89
- package/detail/harvesterhci.io.host/VirtualMachineInstance.vue +0 -134
- package/detail/harvesterhci.io.host/index.vue +0 -243
- package/detail/harvesterhci.io.virtualmachinebackup/index.vue +0 -221
- package/detail/harvesterhci.io.virtualmachineimage.vue +0 -118
- package/detail/kubevirt.io.virtualmachine/VirtualMachineTabs/VirtualMachineBasics.vue +0 -279
- package/detail/kubevirt.io.virtualmachine/VirtualMachineTabs/VirtualMachineEvents.vue +0 -75
- package/detail/kubevirt.io.virtualmachine/VirtualMachineTabs/VirtualMachineKeypairs.vue +0 -114
- package/detail/kubevirt.io.virtualmachine/VirtualMachineTabs/VirtualMachineMigration.vue +0 -79
- package/detail/kubevirt.io.virtualmachine/index.vue +0 -213
- package/edit/harvesterhci.io.cloudtemplate.vue +0 -123
- package/edit/harvesterhci.io.host/HarvesterDisk.vue +0 -262
- package/edit/harvesterhci.io.host/index.vue +0 -533
- package/edit/harvesterhci.io.keypair.vue +0 -112
- package/edit/harvesterhci.io.managedchart/index.vue +0 -25
- package/edit/harvesterhci.io.managedchart/rancher-monitoring.vue +0 -172
- package/edit/harvesterhci.io.networkattachmentdefinition.vue +0 -210
- package/edit/harvesterhci.io.setting/additional-ca.vue +0 -36
- package/edit/harvesterhci.io.setting/backup-target.vue +0 -182
- package/edit/harvesterhci.io.setting/http-proxy.vue +0 -79
- package/edit/harvesterhci.io.setting/index.vue +0 -201
- package/edit/harvesterhci.io.setting/overcommit-config.vue +0 -94
- package/edit/harvesterhci.io.setting/ssl-certificates.vue +0 -117
- package/edit/harvesterhci.io.setting/ssl-parameters.vue +0 -161
- package/edit/harvesterhci.io.setting/support-bundle-image.vue +0 -134
- package/edit/harvesterhci.io.setting/support-bundle-namespaces.vue +0 -73
- package/edit/harvesterhci.io.setting/vip-pools.vue +0 -244
- package/edit/harvesterhci.io.setting/vm-force-reset-policy.vue +0 -81
- package/edit/harvesterhci.io.virtualmachinebackup.vue +0 -256
- package/edit/harvesterhci.io.virtualmachineimage.vue +0 -364
- package/edit/harvesterhci.io.virtualmachinetemplateversion.vue +0 -340
- package/edit/harvesterhci.io.volume.vue +0 -195
- package/edit/kubevirt.io.virtualmachine/VirtualMachineAccessCredentials/AccessCredentialsUsers.vue +0 -190
- package/edit/kubevirt.io.virtualmachine/VirtualMachineAccessCredentials/index.vue +0 -212
- package/edit/kubevirt.io.virtualmachine/VirtualMachineAccessCredentials/type/basicAuth.vue +0 -94
- package/edit/kubevirt.io.virtualmachine/VirtualMachineAccessCredentials/type/sshkey.vue +0 -85
- package/edit/kubevirt.io.virtualmachine/VirtualMachineCloudConfig/DataTemplate.vue +0 -153
- package/edit/kubevirt.io.virtualmachine/VirtualMachineCloudConfig/index.vue +0 -279
- package/edit/kubevirt.io.virtualmachine/VirtualMachineCpuMemory.vue +0 -113
- package/edit/kubevirt.io.virtualmachine/VirtualMachineNetwork/__tests__/HarvesterEditNetwork.test.ts +0 -41
- package/edit/kubevirt.io.virtualmachine/VirtualMachineNetwork/base.vue +0 -281
- package/edit/kubevirt.io.virtualmachine/VirtualMachineNetwork/index.vue +0 -142
- package/edit/kubevirt.io.virtualmachine/VirtualMachineReserved.vue +0 -54
- package/edit/kubevirt.io.virtualmachine/VirtualMachineSSHKey.vue +0 -256
- package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/index.vue +0 -391
- package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/__tests__/HarvesterEditContainer.test.ts +0 -40
- package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/__tests__/HarvesterEditExisting.test.ts +0 -102
- package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/__tests__/HarvesterEditVMImage.test.ts +0 -117
- package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/__tests__/HarvesterEditVolume.test.ts +0 -74
- package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/container.vue +0 -132
- package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/existing.vue +0 -303
- package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/vmImage.vue +0 -285
- package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/volume.vue +0 -188
- package/edit/kubevirt.io.virtualmachine/index.vue +0 -642
- package/edit/network.harvesterhci.io.clusternetwork/index.vue +0 -19
- package/edit/network.harvesterhci.io.clusternetwork/vlan.vue +0 -134
- package/edit/workload/types/Deployment.vue +0 -377
- package/edit/workload/types/Generic.vue +0 -295
- package/list/harvesterhci.io.cloudtemplate.vue +0 -78
- package/list/harvesterhci.io.dashboard/HarvesterUpgrade.vue +0 -211
- package/list/harvesterhci.io.dashboard/UpgradeInfo.vue +0 -40
- package/list/harvesterhci.io.dashboard/index.vue +0 -752
- package/list/harvesterhci.io.host/index.vue +0 -186
- package/list/harvesterhci.io.networkattachmentdefinition.vue +0 -167
- package/list/harvesterhci.io.setting.vue +0 -241
- package/list/harvesterhci.io.virtualmachinebackup.vue +0 -172
- package/list/harvesterhci.io.virtualmachineimage.vue +0 -80
- package/list/harvesterhci.io.virtualmachinetemplateversion.vue +0 -173
- package/list/harvesterhci.io.volume.vue +0 -122
- package/list/kubevirt.io.virtualmachine.vue +0 -193
- package/mixins/harvester-vm/impl.js +0 -267
- package/mixins/harvester-vm/index.js +0 -1357
- package/models/harvester/configmap.js +0 -32
- package/models/harvester/harvesterhci.io.blockdevice.js +0 -55
- package/models/harvester/harvesterhci.io.keypair.js +0 -12
- package/models/harvester/harvesterhci.io.setting.js +0 -127
- package/models/harvester/harvesterhci.io.supportbundle.js +0 -35
- package/models/harvester/harvesterhci.io.upgrade.js +0 -226
- package/models/harvester/harvesterhci.io.virtualmachinebackup.js +0 -116
- package/models/harvester/harvesterhci.io.virtualmachineimage.js +0 -255
- package/models/harvester/harvesterhci.io.virtualmachinerestore.js +0 -43
- package/models/harvester/harvesterhci.io.virtualmachinetemplate.js +0 -69
- package/models/harvester/harvesterhci.io.virtualmachinetemplateversion.js +0 -227
- package/models/harvester/k8s.cni.cncf.io.networkattachmentdefinition.js +0 -32
- package/models/harvester/kubevirt.io.virtualmachine.js +0 -850
- package/models/harvester/kubevirt.io.virtualmachineinstance.js +0 -142
- package/models/harvester/management.cattle.io.managedchart.js +0 -191
- package/models/harvester/management.cattle.io.setting.js +0 -40
- package/models/harvester/network.harvesterhci.io.clusternetwork.js +0 -100
- package/models/harvester/network.harvesterhci.io.nodenetwork.js +0 -34
- package/models/harvester/node.js +0 -255
- package/models/harvester/persistentvolumeclaim.js +0 -166
- package/models/harvester/pod.js +0 -185
- package/pages/c/_cluster/harvester/airgapupgrade/index.vue +0 -309
- package/pages/c/_cluster/harvester/console/_uid/serial.vue +0 -51
- package/pages/c/_cluster/harvester/console/_uid/vnc.vue +0 -52
- package/pages/c/_cluster/harvester/index.vue +0 -24
- package/pages/c/_cluster/harvester/support/index.vue +0 -154
- package/pkg/model-loader.lib.js +0 -3
- package/promptRemove/kubevirt.io.virtualmachine.vue +0 -164
- package/store/harvester-common.js +0 -126
- package/utils/validators/vm-datavolumes.js +0 -38
- package/utils/validators/vm-image.js +0 -32
- package/utils/validators/vm.js +0 -221
package/core/plugins.js
CHANGED
|
@@ -12,10 +12,12 @@ export default function({
|
|
|
12
12
|
redirect
|
|
13
13
|
}, inject) {
|
|
14
14
|
const dynamic = {};
|
|
15
|
+
const validators = {};
|
|
15
16
|
let _lastLoaded = 0;
|
|
16
17
|
|
|
17
18
|
// Track which plugin loaded what, so we can unload stuff
|
|
18
19
|
const plugins = {};
|
|
20
|
+
|
|
19
21
|
const pluginRoutes = new PluginRoutes(app.router);
|
|
20
22
|
|
|
21
23
|
inject('plugin', {
|
|
@@ -43,44 +45,69 @@ export default function({
|
|
|
43
45
|
element.type = 'text/javascript';
|
|
44
46
|
element.async = true;
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
// id is `<product>-<version>`.
|
|
49
|
+
const oldPlugin = Object.values(plugins).find(p => id.startsWith(p.name));
|
|
48
50
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
let removed = Promise.resolve();
|
|
52
|
+
|
|
53
|
+
if (oldPlugin) {
|
|
54
|
+
// Uninstall existing plugin if there is one. This ensures that last loaded plugin is not always used
|
|
55
|
+
// (nav harv1-->harv2-->harv1 and harv2 would be shown)
|
|
56
|
+
removed = this.removePlugin(oldPlugin.name).then(() => {
|
|
57
|
+
delete window[oldPlugin.id];
|
|
58
|
+
|
|
59
|
+
delete plugins[oldPlugin.id];
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
removed.then(() => {
|
|
64
|
+
element.onload = () => {
|
|
65
|
+
element.parentElement.removeChild(element);
|
|
66
|
+
|
|
67
|
+
if (!window[id]) {
|
|
68
|
+
return reject(new Error('Could not load plugin code'));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Update the timestamp that new plugins were loaded - may be needed
|
|
72
|
+
// to update caches when new plugins are loaded
|
|
73
|
+
_lastLoaded = new Date().getTime();
|
|
74
|
+
|
|
75
|
+
// name is the name of the plugin, including the version number
|
|
76
|
+
const plugin = new Plugin(id);
|
|
52
77
|
|
|
53
|
-
|
|
54
|
-
// to update caches when new plugins are loaded
|
|
55
|
-
_lastLoaded = new Date().getTime();
|
|
78
|
+
plugins[id] = plugin;
|
|
56
79
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const plugin = new Plugin(id);
|
|
80
|
+
// Initialize the plugin
|
|
81
|
+
window[id].default(plugin, this.internal());
|
|
60
82
|
|
|
61
|
-
|
|
83
|
+
// Uninstall existing plugin if there is one
|
|
84
|
+
this.removePlugin(plugin.name); // Removing this causes the plugin to not load on refresh
|
|
62
85
|
|
|
63
|
-
|
|
64
|
-
|
|
86
|
+
// Load all of the types etc from the plugin
|
|
87
|
+
this.applyPlugin(plugin);
|
|
65
88
|
|
|
66
|
-
|
|
67
|
-
|
|
89
|
+
// Add the plugin to the store
|
|
90
|
+
store.dispatch('uiplugins/addPlugin', plugin);
|
|
68
91
|
|
|
69
|
-
|
|
70
|
-
|
|
92
|
+
resolve();
|
|
93
|
+
};
|
|
71
94
|
|
|
72
|
-
|
|
73
|
-
|
|
95
|
+
element.onerror = (e) => {
|
|
96
|
+
element.parentElement.removeChild(element);
|
|
97
|
+
// Massage the error into something useful
|
|
98
|
+
const errorMessage = `Failed to load script from '${ e.target.src }'`;
|
|
74
99
|
|
|
75
|
-
|
|
76
|
-
|
|
100
|
+
console.error(errorMessage, e); // eslint-disable-line no-console
|
|
101
|
+
reject(new Error(errorMessage)); // This is more useful where it's used
|
|
102
|
+
};
|
|
77
103
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
};
|
|
104
|
+
document.head.appendChild(element);
|
|
105
|
+
}).catch((e) => {
|
|
106
|
+
const errorMessage = `Failed to unload old plugin${ oldPlugin?.id }`;
|
|
82
107
|
|
|
83
|
-
|
|
108
|
+
console.error(errorMessage, e); // eslint-disable-line no-console
|
|
109
|
+
reject(new Error(errorMessage)); // This is more useful where it's used
|
|
110
|
+
});
|
|
84
111
|
});
|
|
85
112
|
},
|
|
86
113
|
|
|
@@ -114,15 +141,17 @@ export default function({
|
|
|
114
141
|
},
|
|
115
142
|
|
|
116
143
|
// Remove the plugin
|
|
117
|
-
removePlugin(name) {
|
|
144
|
+
async removePlugin(name) {
|
|
118
145
|
const plugin = Object.values(plugins).find(p => p.name === name);
|
|
119
146
|
|
|
120
147
|
if (!plugin) {
|
|
121
148
|
return;
|
|
122
149
|
}
|
|
123
150
|
|
|
151
|
+
const promises = [];
|
|
152
|
+
|
|
124
153
|
plugin.productNames.forEach((product) => {
|
|
125
|
-
store.dispatch('type-map/removeProduct', { product, plugin });
|
|
154
|
+
promises.push(store.dispatch('type-map/removeProduct', { product, plugin }));
|
|
126
155
|
});
|
|
127
156
|
|
|
128
157
|
// Remove all of the types
|
|
@@ -138,13 +167,13 @@ export default function({
|
|
|
138
167
|
|
|
139
168
|
// Remove locales
|
|
140
169
|
plugin.locales.forEach((localeObj) => {
|
|
141
|
-
store.dispatch('i18n/removeLocale', localeObj);
|
|
170
|
+
promises.push(store.dispatch('i18n/removeLocale', localeObj));
|
|
142
171
|
});
|
|
143
172
|
|
|
144
173
|
if (plugin.types.models) {
|
|
145
174
|
// Ask the Steve stores to forget any data it has for models that we are removing
|
|
146
|
-
this.removeTypeFromStore(store, 'rancher', Object.keys(plugin.types.models));
|
|
147
|
-
this.removeTypeFromStore(store, 'management', Object.keys(plugin.types.models));
|
|
175
|
+
promises.push(...this.removeTypeFromStore(store, 'rancher', Object.keys(plugin.types.models)));
|
|
176
|
+
promises.push(...this.removeTypeFromStore(store, 'management', Object.keys(plugin.types.models)));
|
|
148
177
|
}
|
|
149
178
|
|
|
150
179
|
// Uninstall routes
|
|
@@ -154,19 +183,24 @@ export default function({
|
|
|
154
183
|
plugin.uninstallHooks.forEach(fn => fn(plugin, this.internal()));
|
|
155
184
|
|
|
156
185
|
// Remove the plugin itself
|
|
157
|
-
store.dispatch('uiplugins/removePlugin', name);
|
|
186
|
+
promises.push( store.dispatch('uiplugins/removePlugin', name));
|
|
158
187
|
|
|
159
188
|
// Unregister vuex stores
|
|
160
189
|
plugin.stores.forEach(pStore => pStore.unregister(store));
|
|
161
190
|
|
|
191
|
+
// Remove validators
|
|
192
|
+
Object.keys(plugin.validators).forEach((key) => {
|
|
193
|
+
delete validators[key];
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
await Promise.all(promises);
|
|
197
|
+
|
|
162
198
|
// Update last load since we removed a plugin
|
|
163
199
|
_lastLoaded = new Date().getTime();
|
|
164
200
|
},
|
|
165
201
|
|
|
166
202
|
removeTypeFromStore(store, storeName, types) {
|
|
167
|
-
(types || []).
|
|
168
|
-
store.commit(`${ storeName }/forgetType`, type);
|
|
169
|
-
});
|
|
203
|
+
return (types || []).map(type => store.commit(`${ storeName }/forgetType`, type));
|
|
170
204
|
},
|
|
171
205
|
|
|
172
206
|
// Apply the plugin based on its metadata
|
|
@@ -200,6 +234,11 @@ export default function({
|
|
|
200
234
|
|
|
201
235
|
// Routes
|
|
202
236
|
pluginRoutes.addRoutes(plugin, plugin.routes);
|
|
237
|
+
|
|
238
|
+
// Validators
|
|
239
|
+
Object.keys(plugin.validators).forEach((key) => {
|
|
240
|
+
validators[key] = plugin.validators[key];
|
|
241
|
+
});
|
|
203
242
|
},
|
|
204
243
|
|
|
205
244
|
/**
|
|
@@ -252,6 +291,10 @@ export default function({
|
|
|
252
291
|
return dynamic[typeName]?.[name];
|
|
253
292
|
},
|
|
254
293
|
|
|
294
|
+
getValidator(name) {
|
|
295
|
+
return validators[name];
|
|
296
|
+
},
|
|
297
|
+
|
|
255
298
|
// Timestamp that a UI package was last loaded
|
|
256
299
|
// Typically used to invalidate caches (e.g. i18n) when new plugins are loaded
|
|
257
300
|
get lastLoad() {
|
package/core/types.ts
CHANGED
|
@@ -18,6 +18,7 @@ export interface PackageMetadata {
|
|
|
18
18
|
export type VuexStoreObject = { [key: string]: any }
|
|
19
19
|
export type CoreStoreSpecifics = { state: () => VuexStoreObject, getters: VuexStoreObject, mutations: VuexStoreObject, actions: VuexStoreObject }
|
|
20
20
|
export type CoreStoreConfig = { namespace: string, baseUrl?: string, modelBaseClass?: string, supportsStream?: boolean, isClusterStore?: boolean }
|
|
21
|
+
export type CoreStoreInit = (store: any, ctx: any) => void;
|
|
21
22
|
export type RegisterStore = () => (store: any) => void
|
|
22
23
|
export type UnregisterStore = (store: any) => void
|
|
23
24
|
|
|
@@ -56,6 +57,11 @@ export interface IPlugin {
|
|
|
56
57
|
*/
|
|
57
58
|
metadata: PackageMetadata;
|
|
58
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Validators used in the same manner as shell/utils/custom-validators
|
|
62
|
+
*/
|
|
63
|
+
validators: {[key: string]: Function};
|
|
64
|
+
|
|
59
65
|
/**
|
|
60
66
|
* Add a module contains localisations for a specific locale
|
|
61
67
|
*/
|
|
@@ -91,7 +97,7 @@ export interface IPlugin {
|
|
|
91
97
|
* actions, will eventually call a `request` action which will make the raw http request. This is a pkg specific feature so needs the
|
|
92
98
|
* `request` action needs to be supplied in the `storeSpecifics`
|
|
93
99
|
*/
|
|
94
|
-
addDashboardStore(storeName: string, storeSpecifics: CoreStoreSpecifics, config: CoreStoreConfig): void;
|
|
100
|
+
addDashboardStore(storeName: string, storeSpecifics: CoreStoreSpecifics, config: CoreStoreConfig, init?: CoreStoreInit): void;
|
|
95
101
|
|
|
96
102
|
/**
|
|
97
103
|
* Add hooks that will execute when a user navigates
|
|
@@ -321,6 +321,18 @@ export default {
|
|
|
321
321
|
return false;
|
|
322
322
|
},
|
|
323
323
|
|
|
324
|
+
showEksNodeGroupWarning() {
|
|
325
|
+
if ( this.value.isEKS ) {
|
|
326
|
+
const desiredTotal = this.value.eksNodeGroups.filter(g => g.desiredSize === 0);
|
|
327
|
+
|
|
328
|
+
if ( desiredTotal.length === this.value.eksNodeGroups.length ) {
|
|
329
|
+
return true;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
return false;
|
|
334
|
+
},
|
|
335
|
+
|
|
324
336
|
machineHeaders() {
|
|
325
337
|
return [
|
|
326
338
|
STATE,
|
|
@@ -585,6 +597,7 @@ export default {
|
|
|
585
597
|
<Loading v-if="$fetchState.pending" />
|
|
586
598
|
<div v-else>
|
|
587
599
|
<Banner v-if="showWindowsWarning" color="error" :label="t('cluster.banner.os', { newOS: 'Windows', existingOS: 'Linux' })" />
|
|
600
|
+
<Banner v-if="showEksNodeGroupWarning" color="error" :label="t('cluster.banner.desiredNodeGroupWarning')" />
|
|
588
601
|
|
|
589
602
|
<Banner v-if="$fetchState.error" color="error" :label="$fetchState.error" />
|
|
590
603
|
<ResourceTabs v-model="value" :default-tab="defaultTab">
|
|
@@ -120,6 +120,10 @@ export default {
|
|
|
120
120
|
return this.value.type === WORKLOAD_TYPES.CRON_JOB;
|
|
121
121
|
},
|
|
122
122
|
|
|
123
|
+
isPod() {
|
|
124
|
+
return this.value.type === WORKLOAD_TYPES.POD;
|
|
125
|
+
},
|
|
126
|
+
|
|
123
127
|
podSchema() {
|
|
124
128
|
return this.$store.getters['cluster/schemaFor'](POD);
|
|
125
129
|
},
|
|
@@ -133,13 +137,15 @@ export default {
|
|
|
133
137
|
},
|
|
134
138
|
|
|
135
139
|
podTemplateSpec() {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if ( isCronJob ) {
|
|
140
|
+
if ( this.value.type === WORKLOAD_TYPES.CRON_JOB ) {
|
|
139
141
|
return this.value.spec.jobTemplate.spec.template.spec;
|
|
140
|
-
} else {
|
|
141
|
-
return this.value.spec?.template?.spec;
|
|
142
142
|
}
|
|
143
|
+
|
|
144
|
+
if ( this.value.type === WORKLOAD_TYPES.POD ) {
|
|
145
|
+
return this.value;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return this.value.spec?.template?.spec;
|
|
143
149
|
},
|
|
144
150
|
|
|
145
151
|
container() {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/edit/auth/azuread.vue
CHANGED
|
@@ -67,6 +67,10 @@ export default {
|
|
|
67
67
|
|
|
68
68
|
async fetch() {
|
|
69
69
|
await this.reloadModel();
|
|
70
|
+
|
|
71
|
+
if ( this.value?.graphEndpoint ) {
|
|
72
|
+
this.setInitialEndpoint(this.value.graphEndpoint);
|
|
73
|
+
}
|
|
70
74
|
},
|
|
71
75
|
|
|
72
76
|
data() {
|
|
@@ -171,6 +175,16 @@ export default {
|
|
|
171
175
|
}
|
|
172
176
|
},
|
|
173
177
|
|
|
178
|
+
setInitialEndpoint(endpoint) {
|
|
179
|
+
const endpointKey = Object.keys(ENDPOINT_MAPPING).find(key => ENDPOINT_MAPPING[key].graphEndpoint === endpoint);
|
|
180
|
+
|
|
181
|
+
if ( endpointKey ) {
|
|
182
|
+
this.endpoint = endpointKey;
|
|
183
|
+
} else {
|
|
184
|
+
this.endpoint = 'custom';
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
|
|
174
188
|
getNewApplicationSecret() {
|
|
175
189
|
const applicationSecretOrId =
|
|
176
190
|
this.model.applicationSecret || this.applicationSecret;
|
|
@@ -291,7 +305,7 @@ export default {
|
|
|
291
305
|
<InfoBox v-if="!model.enabled" id="reply-info" class="mt-20 mb-20 p-10">
|
|
292
306
|
{{ t('authConfig.azuread.reply.info') }}
|
|
293
307
|
<br />
|
|
294
|
-
<label>{{ t('authConfig.azuread.reply.label') }} </label>
|
|
308
|
+
<label class="reply-url">{{ t('authConfig.azuread.reply.label') }} </label>
|
|
295
309
|
<CopyToClipboardText :plain="true" :text="replyUrl" />
|
|
296
310
|
</InfoBox>
|
|
297
311
|
|
|
@@ -387,4 +401,9 @@ export default {
|
|
|
387
401
|
#reply-info {
|
|
388
402
|
flex-grow: 0;
|
|
389
403
|
}
|
|
404
|
+
|
|
405
|
+
.reply-url {
|
|
406
|
+
color: inherit;
|
|
407
|
+
font-weight: 700;
|
|
408
|
+
}
|
|
390
409
|
</style>
|
|
@@ -16,7 +16,7 @@ import { NAME } from '@shell/config/product/explorer';
|
|
|
16
16
|
import { PROJECT_ID, _VIEW, _CREATE, _EDIT } from '@shell/config/query-params';
|
|
17
17
|
import ProjectMembershipEditor from '@shell/components/form/Members/ProjectMembershipEditor';
|
|
18
18
|
import { canViewProjectMembershipEditor } from '@shell/components/form/Members/ProjectMembershipEditor.vue';
|
|
19
|
-
import {
|
|
19
|
+
import { HARVESTER_NAME as HARVESTER } from '@shell/config/product/harvester-manager';
|
|
20
20
|
import { Banner } from '@components/Banner';
|
|
21
21
|
|
|
22
22
|
export default {
|
|
@@ -188,7 +188,7 @@ export default {
|
|
|
188
188
|
<template>
|
|
189
189
|
<CruResource
|
|
190
190
|
class="project"
|
|
191
|
-
:done-route="
|
|
191
|
+
:done-route="value.listLocation"
|
|
192
192
|
:errors="fvUnreportedValidationErrors"
|
|
193
193
|
:mode="mode"
|
|
194
194
|
:resource="value"
|
package/edit/namespace.vue
CHANGED
|
@@ -15,7 +15,7 @@ import MoveModal from '@shell/components/MoveModal';
|
|
|
15
15
|
import ResourceQuota from '@shell/components/form/ResourceQuota/Namespace';
|
|
16
16
|
import Loading from '@shell/components/Loading';
|
|
17
17
|
import { HARVESTER_TYPES, RANCHER_TYPES } from '@shell/components/form/ResourceQuota/shared';
|
|
18
|
-
import {
|
|
18
|
+
import { HARVESTER_NAME as HARVESTER } from '@shell/config/product/harvester-manager';
|
|
19
19
|
|
|
20
20
|
export default {
|
|
21
21
|
components: {
|
|
@@ -34,9 +34,11 @@ export default {
|
|
|
34
34
|
mixins: [CreateEditView],
|
|
35
35
|
|
|
36
36
|
async fetch() {
|
|
37
|
-
|
|
37
|
+
if (this.$store.getters['management/schemaFor'](MANAGEMENT.PROJECT)) {
|
|
38
|
+
this.projects = await this.$store.dispatch('management/findAll', { type: MANAGEMENT.PROJECT });
|
|
38
39
|
|
|
39
|
-
|
|
40
|
+
this.project = this.projects.find(p => p.id.includes(this.projectName));
|
|
41
|
+
}
|
|
40
42
|
},
|
|
41
43
|
|
|
42
44
|
data() {
|
|
@@ -62,8 +64,9 @@ export default {
|
|
|
62
64
|
|
|
63
65
|
computed: {
|
|
64
66
|
...mapGetters(['isSingleProduct']),
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
|
|
68
|
+
isSingleHarvester() {
|
|
69
|
+
return this.$store.getters['currentProduct'].inStore === HARVESTER && this.isSingleProduct;
|
|
67
70
|
},
|
|
68
71
|
|
|
69
72
|
projectOpts() {
|
|
@@ -93,7 +96,11 @@ export default {
|
|
|
93
96
|
},
|
|
94
97
|
|
|
95
98
|
showResourceQuota() {
|
|
96
|
-
return Object.keys(this.project?.spec?.resourceQuota?.limit || {}).length > 0;
|
|
99
|
+
return !this.isSingleHarvester && Object.keys(this.project?.spec?.resourceQuota?.limit || {}).length > 0;
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
showContainerResourceLimit() {
|
|
103
|
+
return !this.isSingleHarvester;
|
|
97
104
|
}
|
|
98
105
|
},
|
|
99
106
|
|
|
@@ -160,13 +167,13 @@ export default {
|
|
|
160
167
|
:namespaced="false"
|
|
161
168
|
:mode="mode"
|
|
162
169
|
>
|
|
163
|
-
<template v-if="
|
|
170
|
+
<template v-if="project" #project-col>
|
|
164
171
|
<LabeledSelect v-model="projectName" :label="t('namespace.project.label')" :options="projectOpts" />
|
|
165
172
|
</template>
|
|
166
173
|
</NameNsDescription>
|
|
167
174
|
|
|
168
175
|
<Tabbed :side-tabs="true">
|
|
169
|
-
<Tab v-if="
|
|
176
|
+
<Tab v-if="showResourceQuota" :weight="1" name="container-resource-quotas" :label="t('namespace.resourceQuotas')">
|
|
170
177
|
<div class="row">
|
|
171
178
|
<div class="col span-12">
|
|
172
179
|
<p class="helper-text mb-10">
|
|
@@ -177,7 +184,7 @@ export default {
|
|
|
177
184
|
</div>
|
|
178
185
|
<ResourceQuota v-model="value" :mode="mode" :project="project" :types="isHarvester ? HARVESTER_TYPES : RANCHER_TYPES" />
|
|
179
186
|
</Tab>
|
|
180
|
-
<Tab v-if="
|
|
187
|
+
<Tab v-if="showContainerResourceLimit" :weight="0" name="container-resource-limit" :label="t('namespace.containerResourceLimit')">
|
|
181
188
|
<ContainerResourceLimit
|
|
182
189
|
:key="JSON.stringify(containerResourceLimits)"
|
|
183
190
|
:value="containerResourceLimits"
|
|
@@ -200,6 +207,6 @@ export default {
|
|
|
200
207
|
/>
|
|
201
208
|
</Tab>
|
|
202
209
|
</Tabbed>
|
|
203
|
-
<MoveModal />
|
|
210
|
+
<MoveModal v-if="projects" />
|
|
204
211
|
</CruResource>
|
|
205
212
|
</template>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
|
|
3
2
|
import { LabeledInput } from '@components/Form/LabeledInput';
|
|
4
3
|
import { Checkbox } from '@components/Form/Checkbox';
|
|
5
4
|
import { _EDIT } from '@shell/config/query-params';
|
|
@@ -64,11 +63,40 @@ export default {
|
|
|
64
63
|
|
|
65
64
|
data() {
|
|
66
65
|
const parseDuration = (duration) => {
|
|
67
|
-
// The back end stores the timeout in Duration format, for example, "
|
|
68
|
-
// Here we convert that string to an integer.
|
|
69
|
-
const
|
|
66
|
+
// The back end stores the timeout in Duration format, for example, "42d31h10m30s".
|
|
67
|
+
// Here we convert that string to an integer and return the duration as seconds.
|
|
68
|
+
const splitStr = duration.split(/([a-z])/);
|
|
69
|
+
|
|
70
|
+
const durationsAsSeconds = splitStr.reduce((old, neu, idx) => {
|
|
71
|
+
const parsed = parseInt(neu);
|
|
72
|
+
|
|
73
|
+
if ( isNaN(parsed) ) {
|
|
74
|
+
return old;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const interval = splitStr[(idx + 1)];
|
|
78
|
+
|
|
79
|
+
switch (interval) {
|
|
80
|
+
case 'd':
|
|
81
|
+
old.push(parsed * 24 * 60 * 60);
|
|
82
|
+
break;
|
|
83
|
+
case 'h':
|
|
84
|
+
old.push(parsed * 60 * 60);
|
|
85
|
+
break;
|
|
86
|
+
case 'm':
|
|
87
|
+
old.push(parsed * 60);
|
|
88
|
+
break;
|
|
89
|
+
case 's':
|
|
90
|
+
old.push(parsed);
|
|
91
|
+
break;
|
|
92
|
+
default:
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return old;
|
|
97
|
+
}, []);
|
|
70
98
|
|
|
71
|
-
return
|
|
99
|
+
return durationsAsSeconds.reduce((old, neu) => old + neu);
|
|
72
100
|
};
|
|
73
101
|
|
|
74
102
|
return {
|
package/edit/service.vue
CHANGED
|
@@ -22,7 +22,7 @@ import HarvesterServiceAddOnConfig from '@shell/components/HarvesterServiceAddOn
|
|
|
22
22
|
import { clone } from '@shell/utils/object';
|
|
23
23
|
import { POD, CAPI } from '@shell/config/types';
|
|
24
24
|
import { matching } from '@shell/utils/selector';
|
|
25
|
-
import {
|
|
25
|
+
import { HARVESTER_NAME as HARVESTER } from '@shell/config/product/harvester-manager';
|
|
26
26
|
import { allHash } from '@shell/utils/promise';
|
|
27
27
|
import { isHarvesterSatisfiesVersion } from '@shell/utils/cluster';
|
|
28
28
|
import { Port } from '@shell/utils/validators/formRules';
|